Merge branch 'master' of https://git.eclipse.org/r/basyx/basyx

# Conflicts:
#	.gitignore
diff --git a/.gitignore b/.gitignore
index 7053dde..caa84fe 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
+.lck
 *.class
 /components/basys.components/WebContent/WEB-INF/lib/jdbc/postgresql-42.2.2.jar
 /components/basys.components/WebContent/WEB-INF/lib/jersey/ext/aopalliance-repackaged-2.5.0-b42.jar
@@ -58,6 +59,6 @@
 /.vs
 /sdks/dotnet/.vs/BaSyx
 launchSettings.json
+.project
 *.pubxml
-/sdks/dotnet/basyx-components/NewtonsoftJsonAdapter
 Properties
diff --git a/CONTRIBUTING b/CONTRIBUTING
new file mode 100644
index 0000000..23bef6e
--- /dev/null
+++ b/CONTRIBUTING
@@ -0,0 +1,62 @@
+# Contributing to Eclipse Basyx
+
+Thanks for your interest in this project.
+
+## Project description
+
+Eclipse BaSyx collects the implementation results of the research project BaSys
+4.0. An essential goal of BaSys 4.0 is the use of IT technology for production
+systems to enable the concepts of the new Industrie 4.0 paradigm. It develops a
+middleware that integrates traditional production systems (e.g. PLC controllers)
+and state-of-the art IT technology (BPMN engine, SOA) to enable next generation
+of production automation.
+
+* https://projects.eclipse.org/projects/technology.basyx
+
+## Developer resources
+
+Information regarding source code management, builds, coding standards, and
+more.
+
+* https://projects.eclipse.org/projects/technology.basyx/developer
+
+The project maintains the following source code repositories
+
+* https://git.eclipse.org/r/plugins/gitiles/basyx/basyx
+* https://git.eclipse.org/r/plugins/gitiles/basyx/basyx.website
+
+This project uses Bugzilla to track ongoing development and issues.
+
+* Search for issues: https://bugs.eclipse.org/bugs/buglist.cgi?product=Basyx
+* Create a new report:
+   https://bugs.eclipse.org/bugs/enter_bug.cgi?product=Basyx
+
+Be sure to search for existing bugs before you create another one. Remember that
+contributions are always welcome!
+
+## Eclipse Development Process
+
+This Eclipse Foundation open project is governed by the Eclipse Foundation
+Development Process and operates under the terms of the Eclipse IP Policy.
+
+## Eclipse Contributor Agreement
+
+Before your contribution can be accepted by the project team contributors must
+electronically sign the Eclipse Contributor Agreement (ECA).
+
+* http://www.eclipse.org/legal/ECA.php
+
+Commits that are provided by non-committers must have a Signed-off-by field in
+the footer indicating that the author is aware of the terms by which the
+contribution has been provided to the project. The non-committer must
+additionally have an Eclipse Foundation account and must have a signed Eclipse
+Contributor Agreement (ECA) on file.
+
+For more information, please see the Eclipse Committer Handbook:
+https://www.eclipse.org/projects/handbook/#resources-commit
+
+## Contact
+
+Contact the project developers via the project's "dev" list.
+
+* https://dev.eclipse.org/mailman/listinfo/basyx-dev
diff --git a/Jenkinsfile_Cpp b/Jenkinsfile_Cpp
new file mode 100644
index 0000000..b1e0a7f
--- /dev/null
+++ b/Jenkinsfile_Cpp
@@ -0,0 +1,37 @@
+pipeline {
+  agent {
+    kubernetes {
+      label 'basyx-' + env.BRANCH_NAME + '-' + env.BUILD_NUMBER
+      yaml """
+apiVersion: v1
+kind: Pod
+spec:
+  containers:
+  - name: cpp
+    image: iesetps/basyx-ci-cpp:latest
+    resources:
+      requests:
+        memory: "4Gi"
+        cpu: "2.00"
+      limits:
+        memory: "4Gi"
+        cpu: "2.00"
+    command:
+    - cat
+    tty: true
+"""
+    }
+  }
+  stages {
+      stage('C++ SDK Tests') {
+          steps {
+              container('cpp') {
+                  sh '''
+                     chmod +x ./ci/build_cpp.sh
+                     ./ci/build_cpp.sh
+                     '''
+              }
+          }
+      }
+  }
+}
diff --git a/Jenkinsfile_Java b/Jenkinsfile_Java
new file mode 100644
index 0000000..2f513c0
--- /dev/null
+++ b/Jenkinsfile_Java
@@ -0,0 +1,69 @@
+pipeline {
+  agent {
+    kubernetes {
+      label 'basyx-' + env.BRANCH_NAME + '-' + env.BUILD_NUMBER
+      yaml """
+apiVersion: v1
+kind: Pod
+spec:
+  containers:
+  - name: postgresql
+    image: postgres:latest
+    resources:
+      requests:
+        memory: "2Gi"
+        cpu: "0.5"
+      limits:
+        memory: "2Gi"
+        cpu: "0.5"
+    command: 
+    - cat
+    tty: true
+    env:
+    - name: POSTGRES_PASSWORD
+      value: admin
+    - name: PGDATA
+      value: /run/postgresql/data
+  - name: java
+    image: maven:3.6-jdk-8
+    resources:
+      requests:
+        memory: "4Gi"
+        cpu: "1.5"
+      limits:
+        memory: "4Gi"
+        cpu: "1.5"
+    command:
+    - cat
+    tty: true
+    env:
+    - name: MAVEN_CONFIG
+      value: /home/jenkins/agent/.m2
+"""
+    }
+  }
+  stages {
+      stage('Setup PostgreSQL') {
+          steps {
+              container('postgresql') {
+                  sh '''
+                      chmod +x ./ci/init_postgres.sh
+                      ./ci/init_postgres.sh postgres
+                      pg_ctl start
+                      '''
+              }
+          }
+      }
+      stage('Java SDK Tests') {
+          steps {
+              container('java') {
+                  sh '''
+                     mkdir /home/jenkins/agent/.m2
+                     chmod +x ./ci/build_java.sh
+                     ./ci/build_java.sh
+                     '''
+              }
+          }
+      }
+  }
+}
diff --git a/NOTICE b/NOTICE
index de0fa23..41bc327 100644
--- a/NOTICE
+++ b/NOTICE
@@ -19,4 +19,79 @@
 
 ## Third-party Content
 
-TBD
\ No newline at end of file
+Eclipse Milo
+ 
+ * License: EPL 2.0
+ 
+javax.servlet-api
+
+ * License: CDDL
+ 
+javax.ws.rs-api 
+
+ * License: EPL 2.0
+ 
+jersey-client 
+
+ * License: EPL 2.0
+
+jersey-hk2 
+
+ * License: EPL 2.0
+ 
+Tomcat-catalina
+
+ * License: Apache License 2.0
+ 
+Apache poi-ooxml
+
+ * License: Apache License 2.0
+ 
+Logback 
+
+ * License: EPL 1.0
+
+Janino 
+
+ * License: BSD 3
+
+Eclipse Paho
+
+ * License:  EPL 2.0
+ 
+Postgres
+
+ * License: PostgreSQL Licence
+ 
+GSON 
+
+ * License: Apache License 2.0
+ 
+HikariCP 
+
+ * License: EPL 1.0
+ 
+mongodb-driver-sync
+
+ * License: Apache License 2.0
+ 
+spring-data-mongodb
+
+ * License: Apache License 2.0
+ 
+Moquette
+
+ * License: Apache License 2.0
+ 
+
+To be extended
+
+
+## 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.
\ No newline at end of file
diff --git a/ci/build_cpp.sh b/ci/build_cpp.sh
index 055161a..dfa60bc 100644
--- a/ci/build_cpp.sh
+++ b/ci/build_cpp.sh
@@ -13,7 +13,7 @@
 
     mkdir build && cd build
     cmake ../sdks/c++/basys.sdk.cc -DBASYX_UTILITY_PROJECTS=OFF -DBUILD_SHARED_LIBS=ON
-    make all
+    make -j2 all
     ctest
 else
     echo "No files changed in C++ SDK."
diff --git a/components/basys.components/.mvn/wrapper/MavenWrapperDownloader.java b/components/basys.components/.mvn/wrapper/MavenWrapperDownloader.java
new file mode 100644
index 0000000..e76d1f3
--- /dev/null
+++ b/components/basys.components/.mvn/wrapper/MavenWrapperDownloader.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2007-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import java.net.*;
+import java.io.*;
+import java.nio.channels.*;
+import java.util.Properties;
+
+public class MavenWrapperDownloader {
+
+    private static final String WRAPPER_VERSION = "0.5.6";
+    /**
+     * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided.
+     */
+    private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/"
+        + WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar";
+
+    /**
+     * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to
+     * use instead of the default one.
+     */
+    private static final String MAVEN_WRAPPER_PROPERTIES_PATH =
+            ".mvn/wrapper/maven-wrapper.properties";
+
+    /**
+     * Path where the maven-wrapper.jar will be saved to.
+     */
+    private static final String MAVEN_WRAPPER_JAR_PATH =
+            ".mvn/wrapper/maven-wrapper.jar";
+
+    /**
+     * Name of the property which should be used to override the default download url for the wrapper.
+     */
+    private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl";
+
+    public static void main(String args[]) {
+        System.out.println("- Downloader started");
+        File baseDirectory = new File(args[0]);
+        System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath());
+
+        // If the maven-wrapper.properties exists, read it and check if it contains a custom
+        // wrapperUrl parameter.
+        File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH);
+        String url = DEFAULT_DOWNLOAD_URL;
+        if(mavenWrapperPropertyFile.exists()) {
+            FileInputStream mavenWrapperPropertyFileInputStream = null;
+            try {
+                mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile);
+                Properties mavenWrapperProperties = new Properties();
+                mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream);
+                url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url);
+            } catch (IOException e) {
+                System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'");
+            } finally {
+                try {
+                    if(mavenWrapperPropertyFileInputStream != null) {
+                        mavenWrapperPropertyFileInputStream.close();
+                    }
+                } catch (IOException e) {
+                    // Ignore ...
+                }
+            }
+        }
+        System.out.println("- Downloading from: " + url);
+
+        File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH);
+        if(!outputFile.getParentFile().exists()) {
+            if(!outputFile.getParentFile().mkdirs()) {
+                System.out.println(
+                        "- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'");
+            }
+        }
+        System.out.println("- Downloading to: " + outputFile.getAbsolutePath());
+        try {
+            downloadFileFromURL(url, outputFile);
+            System.out.println("Done");
+            System.exit(0);
+        } catch (Throwable e) {
+            System.out.println("- Error downloading");
+            e.printStackTrace();
+            System.exit(1);
+        }
+    }
+
+    private static void downloadFileFromURL(String urlString, File destination) throws Exception {
+        if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) {
+            String username = System.getenv("MVNW_USERNAME");
+            char[] password = System.getenv("MVNW_PASSWORD").toCharArray();
+            Authenticator.setDefault(new Authenticator() {
+                @Override
+                protected PasswordAuthentication getPasswordAuthentication() {
+                    return new PasswordAuthentication(username, password);
+                }
+            });
+        }
+        URL website = new URL(urlString);
+        ReadableByteChannel rbc;
+        rbc = Channels.newChannel(website.openStream());
+        FileOutputStream fos = new FileOutputStream(destination);
+        fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
+        fos.close();
+        rbc.close();
+    }
+
+}
diff --git a/components/basys.components/.mvn/wrapper/maven-wrapper.properties b/components/basys.components/.mvn/wrapper/maven-wrapper.properties
new file mode 100644
index 0000000..642d572
--- /dev/null
+++ b/components/basys.components/.mvn/wrapper/maven-wrapper.properties
@@ -0,0 +1,2 @@
+distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip
+wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/Dockerfile b/components/basys.components/basyx.components.docker/basyx.components.AASServer/Dockerfile
index 3628774..e199c91 100644
--- a/components/basys.components/basyx.components.docker/basyx.components.AASServer/Dockerfile
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/Dockerfile
@@ -5,11 +5,25 @@
 ARG JAR_FILE
 COPY target/${JAR_FILE} /usr/share/basyxExecutable.jar
 COPY target/lib /usr/share/lib
-COPY src/main/resources/context.properties /usr/share/context.properties
+COPY src/main/resources/aas.properties /usr/share/config/aas.properties
+COPY src/main/resources/context.properties /usr/share/config/context.properties
+COPY src/test/resources/dockerMongodb.properties /usr/share/config/mongodb.properties
  
 # Expose the appropriate port. In case of Tomcat, this is 8080.
 ARG PORT
 EXPOSE ${PORT}
  
+# Set the path for the aas configuration file
+ARG AAS_CONFIG_KEY
+ENV ${AAS_CONFIG_KEY} "/usr/share/config/aas.properties"
+
+# Set the path for the context configuration file
+ARG CONTEXT_CONFIG_KEY
+ENV ${CONTEXT_CONFIG_KEY} "/usr/share/config/context.properties"
+
+# Set the path for the mongodb configuration file
+ARG MONGODB_CONFIG_KEY
+ENV ${MONGODB_CONFIG_KEY} "/usr/share/config/mongodb.properties"
+
 # Start the jar
-CMD java -jar "/usr/share/basyxExecutable.jar" "/usr/share/context.properties"
\ No newline at end of file
+CMD java -jar "/usr/share/basyxExecutable.jar"
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/build.bat b/components/basys.components/basyx.components.docker/basyx.components.AASServer/build.bat
new file mode 100644
index 0000000..64f74e3
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/build.bat
@@ -0,0 +1 @@
+../.././mvnw clean install -U -Pdocker -DskipTests
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/build.sh b/components/basys.components/basyx.components.docker/basyx.components.AASServer/build.sh
new file mode 100755
index 0000000..6820ccc
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/build.sh
@@ -0,0 +1,2 @@
+#!/usr/bin/env sh
+../../mvnw clean install -U -Pdocker -DskipTests
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/docker-compose.yml b/components/basys.components/basyx.components.docker/basyx.components.AASServer/docker-compose.yml
new file mode 100644
index 0000000..b55d107
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/docker-compose.yml
@@ -0,0 +1,26 @@
+version: '2.1'
+services:
+
+  aas:
+    image: ${BASYX_IMAGE_NAME}:${BASYX_IMAGE_TAG}
+    container_name: ${BASYX_CONTAINER_NAME}
+    ports:
+      - ${BASYX_HOST_PORT}:${BASYX_CONTAINER_PORT}
+    depends_on:
+      mongodb:
+        condition: service_healthy
+    links:
+      - mongodb
+
+  mongodb:
+    image: mongo:latest
+    container_name: mongodb
+    healthcheck:
+      test: echo 'db.runCommand("ping").ok' | mongo mongodb:27017/test --quiet
+      interval: 3s
+      timeout: 3s
+      retries: 5
+# Possibility to enable authentication
+#    environment:
+#      MONGO_INITDB_ROOT_USERNAME: root
+#      MONGO_INITDB_ROOT_PASSWORD: example
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/pom.xml b/components/basys.components/basyx.components.docker/basyx.components.AASServer/pom.xml
index ca9308f..d73f236 100644
--- a/components/basys.components/basyx.components.docker/basyx.components.AASServer/pom.xml
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/pom.xml
@@ -5,12 +5,21 @@
   <parent>
     <groupId>org.eclipse.basyx</groupId>
     <artifactId>basyx.components.docker</artifactId>
-    <version>0.0.1-SNAPSHOT</version>
+    <version>1.0.0</version>
   </parent>
   
   <artifactId>basyx.components.AASServer</artifactId>
   <name>AAS Server</name>
-<packaging>jar</packaging>
+  
+  	<properties>
+		<!--  
+			basyx.components.executable is the executable class with the definition of the public void main(String[]).
+			It is needed when building the jar in the maven-jar-plugin (see basyx.components.docker/pom.xml) 
+		-->
+		<basyx.components.executable>org.eclipse.basyx.components.aas.executable.AASServerExecutable</basyx.components.executable>
+	</properties>
+  
+	<packaging>jar</packaging>
 	
 	<!-- Define additional plugins that are not included by default -->
 	<!-- Plugin configuration is done in parent project(s) -->
@@ -24,6 +33,37 @@
 		</plugins>
 	</build>
 	
+	<dependencies>
+		<!-- Use MongoDB Java Drivers for db connections -->
+	    <dependency>
+	        <groupId>org.mongodb</groupId>
+	        <artifactId>mongodb-driver-sync</artifactId>
+	        <version>4.0.5</version>
+	    </dependency>
+
+		<!-- Use Spring Data MongoDB for db data management -->		
+		<dependency>
+			<groupId>org.springframework.data</groupId>
+			<artifactId>spring-data-mongodb</artifactId>
+			<version>3.0.1.RELEASE</version>
+		</dependency>
+		
+		<!-- Adds additional classes of the BaSys SDK for tests -->
+		<dependency>
+			<groupId>org.eclipse.basyx</groupId>
+			<artifactId>basyx.sdk</artifactId>
+			<classifier>tests</classifier>
+		</dependency>
+		
+		<!-- Used for reading .aasx files -->
+		<dependency>
+			<groupId>org.apache.poi</groupId>
+			<artifactId>poi-ooxml</artifactId>
+			<version>4.1.2</version>
+		</dependency>
+		
+	</dependencies>
+	
 	<profiles>
 		<profile>
 			<!-- 
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/basyx/components/AASServer/AASServerComponent.java b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/basyx/components/AASServer/AASServerComponent.java
deleted file mode 100644
index ea57c18..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/basyx/components/AASServer/AASServerComponent.java
+++ /dev/null
@@ -1,80 +0,0 @@
-package org.basyx.components.AASServer;
-
-import java.io.IOException;
-
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.basyx.components.AASServer.servlet.AASServerServlet;
-import org.eclipse.basyx.vab.protocol.http.server.AASHTTPServer;
-import org.eclipse.basyx.vab.protocol.http.server.BaSyxContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.xml.sax.SAXException;
-
-/**
- * Component providing an empty AAS server that is able to receive AAS/SMs from
- * remote. It uses the Aggregator API, i.e. AAS should be pushed to
- * ${URL}/aasList
- * 
- * @author schnicke
- *
- */
-public class AASServerComponent {
-	private static Logger logger = LoggerFactory.getLogger(AASServerComponent.class);
-
-	// The server with the servlet that will be created
-	private AASHTTPServer server;
-
-	private String hostName;
-	private int port;
-	private String path;
-	private String docBasePath;
-
-	/**
-	 * Constructs an empty AAS server using the passed arguments
-	 * 
-	 * @param hostName
-	 * @param port
-	 * @param path
-	 * @param docBasePath
-	 */
-	public AASServerComponent(String hostName, int port, String path, String docBasePath) {
-		// Sets the server context
-		this.hostName = hostName;
-		this.port = port;
-		this.path = path;
-		this.docBasePath = docBasePath;
-	}
-
-	/**
-	 * Starts the AASX component at http://${hostName}:${port}/${path}
-	 * 
-	 * @param hostName
-	 * @param port
-	 * @param path
-	 * @param docBasePath
-	 * @throws IOException
-	 * @throws SAXException
-	 * @throws ParserConfigurationException
-	 */
-	public void startComponent() {
-		logger.info("Create the server...");
-		// Init HTTP context and add an XMLAAServlet according to the configuration
-		BaSyxContext context = new BaSyxContext(path, docBasePath, hostName, port);
-		// Create the Servlet for aas
-		context.addServletMapping("/*", new AASServerServlet());
-		server = new AASHTTPServer(context);
-
-		logger.info("Start the server...");
-		server.start();
-	}
-
-	/**
-	 * Retrieves the URL on which the component is providing its HTTP server
-	 * 
-	 * @return
-	 */
-	public String getURL() {
-		return "http://" + hostName + ":" + port + "/" + path;
-	}
-}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/basyx/components/AASServer/executable/AASServerExecutable.java b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/basyx/components/AASServer/executable/AASServerExecutable.java
deleted file mode 100644
index 9d4f9ab..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/basyx/components/AASServer/executable/AASServerExecutable.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package org.basyx.components.AASServer.executable;
-
-import java.io.IOException;
-
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.basyx.components.AASServer.AASServerComponent;
-import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.xml.sax.SAXException;
-
-/**
- * Starts an HTTP server that is able to receive AAS and submodels pushed from
- * remote <br />
- * They are made available at
- * <i>localhost:4000/aasServer/aasList/${aasId}/aas</i>. Submodels are available
- * at
- * <i>localhost:4000/aasServer/aasList/${aasId}/submodels/${submodelId}/submodel</i><br
- * />
- * 
- * @author schnicke
- */
-public class AASServerExecutable {
-	// Creates a Logger based on the current class
-	private static Logger logger = LoggerFactory.getLogger(AASServerExecutable.class);
-
-	public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
-		// Load configuration
-		BaSyxContextConfiguration config = new BaSyxContextConfiguration();
-		if (args.length > 0 && args[0] instanceof String) {
-			// file path available? => load configs from file
-			config.loadFromFile(args[0]);
-		} else {
-			// fallback: load default configs (in resources)
-			config.loadFromResource(BaSyxContextConfiguration.DEFAULT_CONFIG_PATH);
-		}
-
-		AASServerComponent component = new AASServerComponent(config.getHostname(), config.getPort(), config.getContextPath(), config.getDocBasePath());
-		component.startComponent();
-
-		logger.info("BaSyx AAS Server component started");
-	}
-}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/basyx/components/AASServer/servlet/AASServerServlet.java b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/basyx/components/AASServer/servlet/AASServerServlet.java
deleted file mode 100644
index d2796ad..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/basyx/components/AASServer/servlet/AASServerServlet.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package org.basyx.components.AASServer.servlet;
-
-import org.eclipse.basyx.aas.aggregator.AASAggregator;
-import org.eclipse.basyx.aas.aggregator.restapi.AASAggregatorProvider;
-import org.eclipse.basyx.vab.protocol.http.server.VABHTTPInterface;
-
-/**
- * A servlet containing the empty infrastructure needed to support receiving
- * AAS/Submodels by clients and hosting them
- * 
- * @author schnicke
- *
- */
-public class AASServerServlet extends VABHTTPInterface<AASAggregatorProvider> {
-	private static final long serialVersionUID = 1244938902937878401L;
-
-	public AASServerServlet() {
-		super(new AASAggregatorProvider(new AASAggregator()));
-	}
-
-}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/AASServerComponent.java b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/AASServerComponent.java
new file mode 100644
index 0000000..19efa27
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/AASServerComponent.java
@@ -0,0 +1,347 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.components.aas;
+
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.Collection;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.catalina.servlets.DefaultServlet;
+import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
+import org.eclipse.basyx.aas.aggregator.AASAggregator;
+import org.eclipse.basyx.aas.aggregator.api.IAASAggregator;
+import org.eclipse.basyx.aas.aggregator.restapi.AASAggregatorProvider;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
+import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
+import org.eclipse.basyx.aas.restapi.api.IAASAPIFactory;
+import org.eclipse.basyx.aas.restapi.vab.VABAASAPIFactory;
+import org.eclipse.basyx.components.IComponent;
+import org.eclipse.basyx.components.aas.aasx.AASXPackageManager;
+import org.eclipse.basyx.components.aas.aasx.SubmodelFileEndpointLoader;
+import org.eclipse.basyx.components.aas.configuration.AASServerBackend;
+import org.eclipse.basyx.components.aas.configuration.BaSyxAASServerConfiguration;
+import org.eclipse.basyx.components.aas.mongodb.MongoDBAASAggregator;
+import org.eclipse.basyx.components.aas.mqtt.MqttSubmodelAPIFactory;
+import org.eclipse.basyx.components.aas.servlet.AASAggregatorServlet;
+import org.eclipse.basyx.components.configuration.BaSyxConfiguration;
+import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
+import org.eclipse.basyx.components.configuration.BaSyxMongoDBConfiguration;
+import org.eclipse.basyx.components.configuration.BaSyxMqttConfiguration;
+import org.eclipse.basyx.components.json.JSONAASBundleFactory;
+import org.eclipse.basyx.components.xml.XMLAASBundleFactory;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.restapi.api.ISubmodelAPIFactory;
+import org.eclipse.basyx.support.bundle.AASBundle;
+import org.eclipse.basyx.support.bundle.AASBundleDescriptorFactory;
+import org.eclipse.basyx.support.bundle.AASBundleHelper;
+import org.eclipse.basyx.vab.protocol.http.server.BaSyxHTTPServer;
+import org.eclipse.basyx.vab.protocol.http.server.BaSyxContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.xml.sax.SAXException;
+
+/**
+ * Component providing an empty AAS server that is able to receive AAS/SMs from
+ * remote. It uses the Aggregator API, i.e. AAS should be pushed to
+ * ${URL}/shells
+ * 
+ * @author schnicke, espen
+ *
+ */
+public class AASServerComponent implements IComponent {
+	private static Logger logger = LoggerFactory.getLogger(AASServerComponent.class);
+
+	// The server with the servlet that will be created
+	private BaSyxHTTPServer server;
+	private IAASRegistry registry;
+
+	// Configurations
+	private BaSyxContextConfiguration contextConfig;
+	private BaSyxAASServerConfiguration aasConfig;
+	private BaSyxMongoDBConfiguration mongoDBConfig;
+	private BaSyxMqttConfiguration mqttConfig;
+
+	// Initial AASBundle
+	protected Collection<AASBundle> aasBundles;
+
+	/**
+	 * Constructs an empty AAS server using the passed context
+	 */
+	public AASServerComponent(BaSyxContextConfiguration contextConfig) {
+		this.contextConfig = contextConfig;
+		this.aasConfig = new BaSyxAASServerConfiguration();
+	}
+
+	/**
+	 * Constructs an empty AAS server using the passed configuration
+	 */
+	public AASServerComponent(BaSyxContextConfiguration contextConfig, BaSyxAASServerConfiguration aasConfig) {
+		this.contextConfig = contextConfig;
+		this.aasConfig = aasConfig;
+	}
+
+	/**
+	 * Constructs an empty AAS server using the passed configuration
+	 */
+	public AASServerComponent(BaSyxContextConfiguration contextConfig, BaSyxAASServerConfiguration aasConfig,
+			BaSyxMongoDBConfiguration mongoDBConfig) {
+		this.contextConfig = contextConfig;
+		this.aasConfig = aasConfig;
+		this.aasConfig.setAASBackend(AASServerBackend.MONGODB);
+		this.mongoDBConfig = mongoDBConfig;
+	}
+
+	/**
+	 * Sets and enables mqtt connection configuration for this component. Has to be called before the component is
+	 * started. Currently only works for InMemory backend.
+	 * 
+	 * @param configuration
+	 */
+	public void enableMQTT(BaSyxMqttConfiguration configuration) {
+		this.mqttConfig = configuration;
+	}
+
+	/**
+	 * Disables mqtt configuration. Has to be called before the component is started.
+	 */
+	public void disableMQTT() {
+		this.mqttConfig = null;
+	}
+
+	/**
+	 * Sets a registry service for registering AAS that are created during startup
+	 * 
+	 * @param registry
+	 */
+	public void setRegistry(IAASRegistry registry) {
+		this.registry = registry;
+	}
+
+	/**
+	 * Starts the AASX component at http://${hostName}:${port}/${path}
+	 */
+	@Override
+	public void startComponent() {
+		logger.info("Create the server...");
+		// Load the aggregator servlet
+		createRegistryFromUrl();
+		AASAggregatorServlet aggregatorServlet = loadAggregatorServlet();
+
+		// Init HTTP context and add an XMLAASServlet according to the configuration
+		BaSyxContext context = contextConfig.createBaSyxContext();
+		context.addServletMapping("/*", aggregatorServlet);
+
+
+		// An initial AAS has been loaded from the drive?
+		if (aasBundles != null) {
+			// 1. Also provide the files
+			context.addServletMapping("/files/*", new DefaultServlet());
+
+			// 2. Fix the file paths according to the servlet configuration
+			modifyFilePaths(contextConfig.getHostname(), contextConfig.getPort(), contextConfig.getContextPath());
+
+			// 3. Register the initial AAS
+			registerAAS();
+		}
+
+		logger.info("Start the server");
+		server = new BaSyxHTTPServer(context);
+		server.start();
+	}
+
+	/**
+	 * Retrieves the URL on which the component is providing its HTTP server
+	 * 
+	 * @return
+	 */
+	public String getURL() {
+		return contextConfig.getUrl();
+	}
+
+	@Override
+	public void stopComponent() {
+		
+		// Remove all AASs/SMs that were registered on startup
+		AASBundleHelper.deregister(registry, aasBundles);
+		
+		server.shutdown();
+	}
+
+	private String loadBundleString(String filePath) throws IOException {
+		String content;
+		try {
+			content = new String(Files.readAllBytes(Paths.get(filePath)));
+		} catch (IOException e) {
+			logger.info("Could not find a corresponding file. Loading from default resource.");
+			content = BaSyxConfiguration.getResourceString(filePath);
+		}
+		return content;
+	}
+
+	private void loadBundleFromXML(String xmlPath) throws IOException, ParserConfigurationException, SAXException {
+		logger.info("Loading aas from xml \"" + xmlPath + "\"");
+		String xmlContent = loadBundleString(xmlPath);
+		this.aasBundles = new XMLAASBundleFactory(xmlContent).create();
+	}
+
+	private void loadBundleFromJSON(String jsonPath) throws IOException {
+		logger.info("Loading aas from json \"" + jsonPath + "\"");
+		String jsonContent = loadBundleString(jsonPath);
+		this.aasBundles = new JSONAASBundleFactory(jsonContent).create();
+	}
+
+	private void loadBundleFromAASX(String aasxPath)
+			throws IOException, ParserConfigurationException, SAXException, URISyntaxException, InvalidFormatException {
+		logger.info("Loading aas from aasx \"" + aasxPath + "\"");
+
+		// Instantiate the aasx package manager
+		AASXPackageManager packageManager = new AASXPackageManager(aasxPath);
+
+		// Unpack the files referenced by the aas
+		packageManager.unzipRelatedFiles();
+
+		// Retrieve the aas from the package
+		this.aasBundles = packageManager.retrieveAASBundles();
+	}
+
+	private AASAggregatorServlet loadAggregatorServlet() {
+		// Load the initial AAS bundles from given source
+		loadAASFromSource(aasConfig.getAASSource());
+
+		// Load the aggregator
+		IAASAggregator aggregator = loadAASAggregator();
+
+		// Integrate the loaded bundles into the aggregator
+		if (aasBundles != null) {
+			AASBundleHelper.integrate(aggregator, aasBundles);
+		}
+
+		// Return the servlet for the resulting aggregator
+		return new AASAggregatorServlet(aggregator);
+	}
+
+	private void loadAASFromSource(String aasSource) {
+		if (aasSource.isEmpty()) {
+			return;
+		}
+
+		try {
+			if (aasSource.endsWith(".aasx")) {
+				loadBundleFromAASX(aasSource);
+			} else if (aasSource.endsWith(".json")) {
+				loadBundleFromJSON(aasSource);
+			} else if (aasSource.endsWith(".xml")) {
+				loadBundleFromXML(aasSource);
+			}
+		} catch (IOException | ParserConfigurationException | SAXException | URISyntaxException | InvalidFormatException e) {
+			logger.error("Could not load initial AAS from source '" + aasSource + "'");
+			logger.info("Starting empty server instead");
+		}
+	}
+
+	/**
+	 * Only creates the registry, if it hasn't been set explicitly before
+	 */
+	private void createRegistryFromUrl() {
+		if (this.registry != null) {
+			// Do not overwrite an explicitly set registry
+			return;
+		}
+		// Load registry url from config
+		String registryUrl = this.aasConfig.getRegistry();
+		if (registryUrl != null && !registryUrl.isEmpty()) {
+			registry = new AASRegistryProxy(registryUrl);
+			logger.info("Registry loaded at \"" + registryUrl + "\"");
+		}
+	}
+
+	private void registerAAS() {
+		if (registry != null) {
+			Set<AASDescriptor> descriptors = retrieveDescriptors(contextConfig.getUrl());
+			descriptors.stream().forEach(registry::register);
+		} else {
+			logger.info("No registry specified, skipped registration");
+		}
+	}
+
+	/**
+	 * Returns the set of AAS descriptors for the AAS contained in the AASX
+	 * 
+	 * @param hostBasePath
+	 *                     the path to the server; helper method for e.g. virtualization
+	 *                     environments
+	 * @return
+	 */
+	private Set<AASDescriptor> retrieveDescriptors(String hostBasePath) {
+		// Base path + aggregator accessor
+		final String fullBasePath = hostBasePath + "/" + AASAggregatorProvider.PREFIX;
+
+		return aasBundles.stream().map(b -> AASBundleDescriptorFactory.createAASDescriptor(b, fullBasePath))
+				.collect(Collectors.toSet());
+	}
+
+	/**
+	 * Fixes the File submodel element value paths according to the given endpoint configuration
+	 */
+	private void modifyFilePaths(String hostName, int port, String rootPath) {
+		rootPath = rootPath + "/files";
+		for (AASBundle bundle : aasBundles) {
+			Set<ISubmodel> submodels = bundle.getSubmodels();
+			for (ISubmodel sm : submodels) {
+				SubmodelFileEndpointLoader.setRelativeFileEndpoints(sm, hostName, port, rootPath);
+			}
+		}
+	}
+
+	/**
+	 * Loads a aas aggregator servlet with a backend according to the configuration
+	 * 
+	 * @return
+	 */
+	private IAASAggregator loadAASAggregator() {
+		// Get aggregator according to backend config
+		AASServerBackend backendType = aasConfig.getAASBackend();
+		IAASAggregator aggregator = null;
+		if (backendType == AASServerBackend.INMEMORY && mqttConfig == null) {
+			logger.info("Using InMemory backend");
+			aggregator = new AASAggregator(registry);
+		} else if (backendType == AASServerBackend.INMEMORY && mqttConfig != null) {
+			logger.info("Using InMemory backend with MQTT providers");
+			IAASAPIFactory aasApiProvider = new VABAASAPIFactory();
+			ISubmodelAPIFactory smApiProvider = new MqttSubmodelAPIFactory(mqttConfig);
+			aggregator = new AASAggregator(aasApiProvider, smApiProvider, registry);
+		} else if ( backendType == AASServerBackend.MONGODB ) {
+			logger.info("Using MongoDB backend");
+			aggregator = loadMongoDBAggregator();
+		}
+
+		return aggregator;
+	}
+
+	private IAASAggregator loadMongoDBAggregator() {
+		BaSyxMongoDBConfiguration config;
+		if (this.mongoDBConfig == null) {
+			config = new BaSyxMongoDBConfiguration();
+			config.loadFromDefaultSource();
+		} else {
+			config = this.mongoDBConfig;
+		}
+		MongoDBAASAggregator aggregator = new MongoDBAASAggregator(config);
+		aggregator.setRegistry(registry);
+		return aggregator;
+	}
+}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/aasx/AASXPackageManager.java b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/aasx/AASXPackageManager.java
new file mode 100644
index 0000000..4f8179b
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/aasx/AASXPackageManager.java
@@ -0,0 +1,285 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.components.aas.aasx;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringWriter;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOUtils;
+import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
+import org.apache.poi.openxml4j.opc.OPCPackage;
+import org.apache.poi.openxml4j.opc.PackagePart;
+import org.apache.poi.openxml4j.opc.PackageRelationshipCollection;
+import org.apache.poi.openxml4j.opc.PackagingURIHelper;
+import org.eclipse.basyx.components.configuration.BaSyxConfiguration;
+import org.eclipse.basyx.components.xml.XMLAASBundleFactory;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElementCollection;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IFile;
+import org.eclipse.basyx.support.bundle.AASBundle;
+import org.eclipse.basyx.vab.modelprovider.VABPathTools;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.xml.sax.SAXException;
+
+/**
+ * The AASX package converter converts a aasx package into a list of aas, a list
+ * of submodels a list of assets, a list of Concept descriptions
+ * 
+ * The aas provides the references to the submodels and assets
+ * 
+ * @author zhangzai, conradi
+ *
+ */
+public class AASXPackageManager {
+
+
+	private static final String XML_TYPE = "http://www.admin-shell.io/aasx/relationships/aas-spec";
+	private static final String AASX_ORIGIN = "/aasx/aasx-origin";
+	
+	
+	/**
+	 * Path to the AASX package
+	 */
+	private String aasxPath;
+
+	/**
+	 * AAS bundle factory
+	 */
+	private XMLAASBundleFactory bundleFactory;
+	
+	/**
+	 * Cache for generated Bundles
+	 */
+	private Set<AASBundle> bundles;
+
+	/**
+	 * Logger
+	 */
+	private static Logger logger = LoggerFactory.getLogger(AASXPackageManager.class);
+
+	/**
+	 * Constructor
+	 */
+	public AASXPackageManager(String path) {
+		aasxPath = path;
+	}
+
+	public Set<AASBundle> retrieveAASBundles() throws IOException, ParserConfigurationException, SAXException, InvalidFormatException {
+		
+		// If the XML was already parsed return cached Bundles
+		if(bundles != null) {
+			return bundles;
+		}
+		
+		OPCPackage aasxRoot = OPCPackage.open(getInputStream(aasxPath));
+		
+		bundleFactory = new XMLAASBundleFactory(getXMLResourceString(aasxRoot));
+		
+		bundles = bundleFactory.create();
+		
+		return bundles;
+	}
+
+	/**
+	 * Return the Content of the xml file in the aasx-package as String
+	 * 
+	 * @param aasxPackage - the root package of the AASX
+	 * @return Content of XML as String
+	 * @throws InvalidFormatException 
+	 * @throws IOException
+	 */
+	private String getXMLResourceString(OPCPackage aasxPackage) throws InvalidFormatException, IOException {
+
+		// Get the "/aasx/aasx-origin" Part. It is Relationship source for the XML-Document
+		PackagePart originPart = aasxPackage.getPart(PackagingURIHelper.createPartName(AASX_ORIGIN));
+		
+		// Get the Relation to the XML Document
+		PackageRelationshipCollection originRelationships = originPart.getRelationshipsByType(XML_TYPE);
+		
+		
+		// If there is more than one or no XML-Document that is an error
+		if(originRelationships.size() > 1) {
+			throw new RuntimeException("More than one 'aasx-spec' document found in .aasx");
+		} else if(originRelationships.size() == 0) {
+			throw new RuntimeException("No 'aasx-spec' document found in .aasx");
+		}
+		
+		// Get the PackagePart of the XML-Document
+		PackagePart xmlPart = originPart.getRelatedPart(originRelationships.getRelationship(0));
+		
+		// Read the content from the PackagePart
+		InputStream stream = xmlPart.getInputStream();
+		StringWriter writer = new StringWriter();
+		IOUtils.copy(stream, writer, StandardCharsets.UTF_8);
+		return writer.toString();
+	}
+
+	/**
+	 * Load the referenced filepaths in the submodels such as PDF, PNG files from
+	 * the package
+	 * 
+	 * @return a map of the folder name and folder path, the folder holds the files
+	 * @throws IOException
+	 * @throws SAXException
+	 * @throws ParserConfigurationException
+	 * @throws InvalidFormatException 
+	 * 
+	 */
+	private List<String> parseReferencedFilePathsFromAASX()
+			throws IOException, ParserConfigurationException, SAXException, InvalidFormatException {
+		
+		Set<AASBundle> bundles = retrieveAASBundles();
+		
+		List<ISubmodel> submodels = new ArrayList<>();
+		
+		// Get the Submodels from all AASBundles
+		for(AASBundle bundle: bundles) {
+			submodels.addAll(bundle.getSubmodels());
+		}
+		
+		List<String> paths = new ArrayList<String>();
+
+		for(ISubmodel sm: submodels) {
+			paths.addAll(parseElements(sm.getSubmodelElements().values()));
+		}
+		return paths;
+	}
+	
+	/**
+	 * Gets the paths from a collection of ISubmodelElement
+	 * 
+	 * @param elements
+	 * @return the Paths from the File elements
+	 */
+	private List<String> parseElements(Collection<ISubmodelElement> elements) {
+		List<String> paths = new ArrayList<String>();
+		
+		for(ISubmodelElement element: elements) {
+			if(element instanceof IFile) {
+				IFile file = (IFile) element;
+				// If the path contains a "://", we can assume, that the Path is a link to an other server
+				// e.g. http://localhost:8080/aasx/...
+				if(!file.getValue().contains("://")) {
+					paths.add(file.getValue());
+				}
+			}
+			else if(element instanceof ISubmodelElementCollection) {
+				ISubmodelElementCollection collection = (ISubmodelElementCollection) element;
+				paths.addAll(parseElements(collection.getSubmodelElements().values()));
+			}
+		}
+		return paths;
+	}
+
+	/**
+	 * Unzips all files referenced by the aasx file according to its relationships
+	 * 
+	 * 
+	 * @throws IOException
+	 * @throws SAXException
+	 * @throws ParserConfigurationException
+	 * @throws URISyntaxException
+	 * @throws InvalidFormatException 
+	 */
+	public void unzipRelatedFiles()
+			throws IOException, ParserConfigurationException, SAXException, URISyntaxException, InvalidFormatException {
+		// load folder which stores the files
+		List<String> files = parseReferencedFilePathsFromAASX();
+		OPCPackage aasxRoot = OPCPackage.open(getInputStream(aasxPath));
+		for (String filePath : files) {
+			// name of the folder
+			unzipFile(filePath, aasxRoot);
+		}
+	}
+
+	/**
+	 * Create a folder to hold the unpackaged files The folder has the path
+	 * \target\classes\docs
+	 * 
+	 * @throws IOException
+	 * @throws URISyntaxException
+	 */
+	private Path getRootFolder() throws IOException, URISyntaxException {
+		URI uri = AASXPackageManager.class.getProtectionDomain().getCodeSource().getLocation().toURI();
+		URI parent = new File(uri).getParentFile().toURI();
+		return Paths.get(parent);
+	}
+
+	/**
+	 * unzip the file folders
+	 * 
+	 * @param filePath - path of the file in the aasx to unzip
+	 * @param aasxPath    - aasx path
+	 * @throws IOException
+	 * @throws URISyntaxException
+	 * @throws InvalidFormatException 
+	 */
+	private void unzipFile(String filePath, OPCPackage aasxRoot) throws IOException, URISyntaxException, InvalidFormatException {
+		// Create destination directory
+		if (filePath.startsWith("/")) {
+			filePath = filePath.substring(1);
+		}
+		if(filePath.isEmpty()) {
+			logger.warn("A file with empty path can not be unzipped.");
+			return;
+		}
+		logger.info("Unzipping " + filePath + " to root folder:");
+		String relativePath = "files/" + VABPathTools.getParentPath(filePath);
+		Path rootPath = getRootFolder();
+		Path destDir = rootPath.resolve(relativePath);
+		logger.info("Unzipping to " + destDir);
+		Files.createDirectories(destDir);
+		
+		PackagePart part = aasxRoot.getPart(PackagingURIHelper.createPartName("/" + filePath));
+		
+		if(part == null) {
+			logger.warn("File '" + filePath + "' could not be unzipped. It does not exist in .aasx.");
+			return;
+		}
+		
+		String targetPath = destDir.toString() + "/" + VABPathTools.getLastElement(filePath);
+		InputStream stream = part.getInputStream();
+		FileUtils.copyInputStreamToFile(stream, new File(targetPath));
+	}
+	
+	private InputStream getInputStream(String aasxFilePath) throws IOException {
+		InputStream stream = BaSyxConfiguration.getResourceStream(aasxFilePath);
+		if(stream != null) {
+			return stream;
+		} else {
+			// Alternativ, if resource has not been found: load from a file
+			try {
+				return new FileInputStream(aasxFilePath);
+			} catch (FileNotFoundException e) {
+				logger.error("File '" + aasxFilePath + "' to be loaded was not found.");
+				throw e;
+			}
+		}
+	}
+}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/aasx/SubmodelFileEndpointLoader.java b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/aasx/SubmodelFileEndpointLoader.java
new file mode 100644
index 0000000..b539ade
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/aasx/SubmodelFileEndpointLoader.java
@@ -0,0 +1,91 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.components.aas.aasx;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Map;
+
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElementCollection;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.File;
+
+/**
+ * A utility class for configuring file endpoints in submodels
+ * 
+ * @author espen
+ *
+ */
+public class SubmodelFileEndpointLoader {
+	/**
+	 * Sets all file and blob submodelElements inside of the submodel to an endpoint at a given host relative
+	 * to its original path.
+	 * 
+	 * @param submodel
+	 * @param host     e.g. localhost
+	 * @param port     port for the host
+	 * @param path     path at which the files are hosted on the host (e.g. "/files")
+	 */
+	public static void setRelativeFileEndpoints(ISubmodel submodel, String host, int port, String path) {
+		String fileRoot = "http://" + host + ":" + port + path;
+		setRelativeFileEndpoints(submodel, fileRoot);
+	}
+
+	/**
+	 * Sets all file and blob submodelElements inside of the submodel to an endpoint at a given host relative
+	 * to its original path.
+	 * 
+	 * @param submodel
+	 * @param fileRoot the full root path for the files (e.g. "http://localhost:1234/myFiles")
+	 */
+	public static void setRelativeFileEndpoints(ISubmodel submodel, String fileRoot) {
+		Map<String, ISubmodelElement> elements = submodel.getSubmodelElements();
+		setMapEndpoints(elements, fileRoot);
+	}
+
+	/**
+	 * Fixes endpoints in a Map of submodel elements (applicable for Submodels and SubmodelElementCollections)
+	 * 
+	 * @param elements
+	 * @param fileRoot
+	 */
+	private static void setMapEndpoints(Map<String, ISubmodelElement> elements, String fileRoot) {
+		elements.values().stream().forEach(e -> {
+			if (e instanceof File) {
+				File file = (File) e;
+				setFileEndpoint(file, fileRoot);
+			} else if (e instanceof ISubmodelElementCollection) {
+				SubmodelElementCollection col = (SubmodelElementCollection) e;
+				setMapEndpoints(col.getSubmodelElements(), fileRoot);
+			}
+		});
+	}
+
+	/**
+	 * Modifies the file value endpoint in a single given file according to a new file root path
+	 * 
+	 * @param file
+	 * @param fileRoot
+	 */
+	private static void setFileEndpoint(File file, String fileRoot) {
+		String relativePath = file.getValue();
+		URL url;
+		try {
+			url = new URL(file.getValue());
+			relativePath = url.getPath();
+		} catch (MalformedURLException e1) {
+			// assume that the file value is already a relative path
+		}
+		String newEndpoint = fileRoot + relativePath;
+		file.setValue(newEndpoint);
+	}
+}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/configuration/AASEventBackend.java b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/configuration/AASEventBackend.java
new file mode 100644
index 0000000..45b60bc
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/configuration/AASEventBackend.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.components.aas.configuration;
+
+import org.eclipse.basyx.submodel.metamodel.enumhelper.StandardizedLiteralEnumHelper;
+
+import com.google.common.base.Strings;
+
+/**
+ * Possible types for AAS event backends.
+ * 
+ * @author espen
+ *
+ */
+public enum AASEventBackend {
+	/**
+	 * Enum values of KeyElements
+	 */
+	NONE("NONE"), MQTT("MQTT");
+	
+	private String literal;
+
+	private AASEventBackend(String literal) {
+		this.literal = literal;
+	}
+
+	@Override
+	public String toString() {
+		return literal;
+	}
+
+	/**
+	 * Method to transform string literal to AAS event enum.
+	 * 
+	 * @see StandardizedLiteralEnumHelper StandardizedLiteralEnumHelper
+	 * 
+	 * @param literal
+	 * @return
+	 */
+	public static AASEventBackend fromString(String literal) {
+		if (Strings.isNullOrEmpty(literal)) {
+			return null;
+		}
+
+		AASEventBackend[] enumConstants = AASEventBackend.class.getEnumConstants();
+		for (AASEventBackend constant : enumConstants) {
+			if (constant.toString().equals(literal)) {
+				return constant;
+			}
+		}
+		throw new IllegalArgumentException("The literal '" + literal + "' is not a valid EventBackend");
+	}
+}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/configuration/AASServerBackend.java b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/configuration/AASServerBackend.java
new file mode 100644
index 0000000..30c0d36
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/configuration/AASServerBackend.java
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.components.aas.configuration;
+
+import org.eclipse.basyx.submodel.metamodel.enumhelper.StandardizedLiteralEnumHelper;
+
+import com.google.common.base.Strings;
+
+/**
+ * Possible types for AAS backends.
+ * 
+ * @author espen
+ *
+ */
+public enum AASServerBackend {
+	/**
+	 * Enum values of KeyElements
+	 */
+	INMEMORY("InMemory"),
+	MONGODB("MongoDB");
+	
+	private String literal;
+
+	private AASServerBackend(String literal) {
+		this.literal = literal;
+	}
+
+	@Override
+	public String toString() {
+		return literal;
+	}
+
+	/**
+	 * Method to transform string literal to AASBackend enum.
+	 * 
+	 * @see StandardizedLiteralEnumHelper StandardizedLiteralEnumHelper
+	 * 
+	 * @param literal
+	 * @return
+	 */
+	public static AASServerBackend fromString(String literal) {
+		if (Strings.isNullOrEmpty(literal)) {
+			return null;
+		}
+
+		AASServerBackend[] enumConstants = AASServerBackend.class.getEnumConstants();
+		for (AASServerBackend constant : enumConstants) {
+			if (constant.toString().equals(literal)) {
+				return constant;
+			}
+		}
+		throw new IllegalArgumentException("The literal '" + literal + "' is not a valid RegistryBackend");
+	}
+}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/configuration/BaSyxAASServerConfiguration.java b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/configuration/BaSyxAASServerConfiguration.java
new file mode 100644
index 0000000..df49876
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/configuration/BaSyxAASServerConfiguration.java
@@ -0,0 +1,141 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.components.aas.configuration;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.basyx.components.configuration.BaSyxConfiguration;
+
+/**
+ * Represents a BaSyx server configuration for an AAS Server with any backend,
+ * that can be loaded from a properties file.
+ * 
+ * @author espen
+ *
+ */
+public class BaSyxAASServerConfiguration extends BaSyxConfiguration {
+	// Prefix for environment variables
+	public static final String ENV_PREFIX = "BaSyxAAS_";
+
+	// Default BaSyx AAS configuration
+	public static final String DEFAULT_BACKEND = AASServerBackend.INMEMORY.toString();
+	public static final String DEFAULT_SOURCE = "";
+	public static final String DEFAULT_REGISTRY = "";
+	public static final String DEFAULT_EVENTS = AASEventBackend.NONE.toString();
+
+	// Configuration keys
+	public static final String REGISTRY = "registry.path";
+	public static final String BACKEND = "aas.backend";
+	public static final String SOURCE = "aas.source";
+	public static final String EVENTS = "aas.events";
+
+	// The default path for the context properties file
+	public static final String DEFAULT_CONFIG_PATH = "aas.properties";
+
+	// The default key for variables pointing to the configuration file
+	public static final String DEFAULT_FILE_KEY = "BASYX_AAS";
+
+	public static Map<String, String> getDefaultProperties() {
+		Map<String, String> defaultProps = new HashMap<>();
+		defaultProps.put(BACKEND, DEFAULT_BACKEND);
+		defaultProps.put(SOURCE, DEFAULT_SOURCE);
+		defaultProps.put(REGISTRY, DEFAULT_REGISTRY);
+		defaultProps.put(EVENTS, DEFAULT_EVENTS);
+		return defaultProps;
+	}
+
+	/**
+	 * Empty Constructor - use default values
+	 */
+	public BaSyxAASServerConfiguration() {
+		super(getDefaultProperties());
+	}
+
+	/**
+	 * Constructor with initial configuration
+	 * 
+	 * @param backend
+	 *            The backend for the AASServer
+	 * @param source
+	 *            The file source for the AASServer (e.g. an .aasx file)
+	 */
+	public BaSyxAASServerConfiguration(AASServerBackend backend, String source) {
+		super(getDefaultProperties());
+		setAASBackend(backend);
+		setAASSource(source);
+	}
+
+	/**
+	 * Constructor with initial configuration values
+	 * 
+	 * @param backend
+	 *            The backend for the AASServer
+	 * @param source
+	 *            The file source for the AASServer (e.g. an .aasx file)
+	 * @param registryUrl
+	 *            The url to the registry
+	 */
+	public BaSyxAASServerConfiguration(AASServerBackend backend, String source, String registryUrl) {
+		super(getDefaultProperties());
+		setAASBackend(backend);
+		setAASSource(source);
+		setRegistry(registryUrl);
+	}
+
+	/**
+	 * Constructor with predefined value map
+	 */
+	public BaSyxAASServerConfiguration(Map<String, String> values) {
+		super(values);
+	}
+
+	public void loadFromEnvironmentVariables() {
+		String[] properties = { REGISTRY, BACKEND, SOURCE, EVENTS };
+		loadFromEnvironmentVariables(ENV_PREFIX, properties);
+	}
+
+	public void loadFromDefaultSource() {
+		loadFileOrDefaultResource(DEFAULT_FILE_KEY, DEFAULT_CONFIG_PATH);
+		loadFromEnvironmentVariables();
+	}
+
+	public AASServerBackend getAASBackend() {
+		return AASServerBackend.fromString(getProperty(BACKEND));
+	}
+
+	public void setAASBackend(AASServerBackend backend) {
+		setProperty(BACKEND, backend.toString());
+	}
+
+	public AASEventBackend getAASEvents() {
+		return AASEventBackend.fromString(getProperty(EVENTS));
+	}
+
+	public void setAASEvents(AASEventBackend events) {
+		setProperty(EVENTS, events.toString());
+	}
+
+	public String getAASSource() {
+		return getProperty(SOURCE);
+	}
+
+	public void setAASSource(String source) {
+		setProperty(SOURCE, source);
+	}
+
+	public String getRegistry() {
+		return getProperty(REGISTRY);
+	}
+
+	public void setRegistry(String registryPath) {
+		setProperty(REGISTRY, registryPath);
+	}
+}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/executable/AASServerExecutable.java b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/executable/AASServerExecutable.java
new file mode 100644
index 0000000..58527c2
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/executable/AASServerExecutable.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.components.aas.executable;
+
+import java.io.File;
+import java.net.URISyntaxException;
+
+import org.eclipse.basyx.components.aas.AASServerComponent;
+import org.eclipse.basyx.components.aas.configuration.AASEventBackend;
+import org.eclipse.basyx.components.aas.configuration.BaSyxAASServerConfiguration;
+import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
+import org.eclipse.basyx.components.configuration.BaSyxMqttConfiguration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Starts an HTTP server that is able to receive AAS and submodels pushed from
+ * remote <br />
+ * They are made available at
+ * <i>localhost:4000/aasServer/shells/${aasId}/aas</i>. Submodels are available
+ * at
+ * <i>localhost:4000/aasServer/shells/${aasId}/submodels/${submodelId}/submodel</i><br
+ * />
+ * 
+ * @author schnicke, espen
+ */
+public class AASServerExecutable {
+	// Creates a Logger based on the current class
+	private static Logger logger = LoggerFactory.getLogger(AASServerExecutable.class);
+
+	public static void main(String[] args) throws URISyntaxException {
+		logger.info("Starting BaSyx AASServer component...");
+		// Load context configuration
+		BaSyxContextConfiguration contextConfig = new BaSyxContextConfiguration();
+		contextConfig.loadFromDefaultSource();
+
+		// Load aas configuration
+		BaSyxAASServerConfiguration aasConfig = new BaSyxAASServerConfiguration();
+		aasConfig.loadFromDefaultSource();
+
+		// Load the additional file path relative to the executed jar file
+		String rootPath = new File(AASServerExecutable.class.getProtectionDomain().getCodeSource().getLocation().toURI()).getParentFile().getPath();
+		String docBasePath = rootPath;
+		contextConfig.setDocBasePath(docBasePath);
+
+		AASServerComponent component = new AASServerComponent(contextConfig, aasConfig);
+
+		// If enabled, load mqtt configuration
+		if (aasConfig.getAASEvents().equals(AASEventBackend.MQTT)) {
+			BaSyxMqttConfiguration mqttConfig = new BaSyxMqttConfiguration();
+			mqttConfig.loadFromDefaultSource();
+			component.enableMQTT(mqttConfig);
+		}
+
+		component.startComponent();
+
+		logger.info("BaSyx AAS Server component started");
+	}
+}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/mongodb/MongoDBAASAPI.java b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/mongodb/MongoDBAASAPI.java
new file mode 100644
index 0000000..6ae87c1
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/mongodb/MongoDBAASAPI.java
@@ -0,0 +1,164 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.components.aas.mongodb;
+
+import static org.springframework.data.mongodb.core.query.Criteria.where;
+import static org.springframework.data.mongodb.core.query.Query.query;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+import org.eclipse.basyx.aas.restapi.api.IAASAPI;
+import org.eclipse.basyx.components.configuration.BaSyxMongoDBConfiguration;
+import org.eclipse.basyx.submodel.metamodel.api.reference.IKey;
+import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Identifiable;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.springframework.data.mongodb.core.MongoOperations;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.data.mongodb.core.query.Query;
+
+import com.mongodb.client.MongoClient;
+import com.mongodb.client.MongoClients;
+
+/**
+ * Implements the IAASAPI for a mongoDB backend.
+ * 
+ * @author espen
+ */
+public class MongoDBAASAPI implements IAASAPI {
+	private static final String DEFAULT_CONFIG_PATH = "mongodb.properties";
+	private static final String AASIDPATH = Identifiable.IDENTIFICATION + "." + Identifier.ID;
+
+	protected BaSyxMongoDBConfiguration config;
+	protected MongoOperations mongoOps;
+	protected String collection;
+	protected String aasId;
+
+	/**
+	 * Receives the path of the configuration.properties file in it's constructor.
+	 * 
+	 * @param configFilePath
+	 */
+	public MongoDBAASAPI(BaSyxMongoDBConfiguration config, String aasId) {
+		this.setConfiguration(config);
+		this.setAASId(aasId);
+	}
+
+	/**
+	 * Receives the path of the .properties file in it's constructor from a resource.
+	 */
+	public MongoDBAASAPI(String resourceConfigPath, String aasId) {
+		config = new BaSyxMongoDBConfiguration();
+		config.loadFromResource(resourceConfigPath);
+		this.setConfiguration(config);
+		this.setAASId(aasId);
+	}
+
+	/**
+	 * Constructor using default sql connections
+	 */
+	public MongoDBAASAPI(String aasId) {
+		this(DEFAULT_CONFIG_PATH, aasId);
+	}
+
+	public void setConfiguration(BaSyxMongoDBConfiguration config) {
+		this.config = config;
+		MongoClient client = MongoClients.create(config.getConnectionUrl());
+		this.mongoOps = new MongoTemplate(client, config.getDatabase());
+		this.collection = config.getAASCollection();
+	}
+
+	/**
+	 * Sets the aas id, so that this API points to the aas with aasId. Can be changed
+	 * to point to a different aas in the database.
+	 * 
+	 * @param smId
+	 */
+	public void setAASId(String aasId) {
+		this.aasId = aasId;
+	}
+
+	/**
+	 * Depending on whether the model is already in the db, this method inserts or replaces the existing data.
+	 * The new aas id for this API is taken from the given aas.
+	 * 
+	 * @param sm
+	 */
+	public void setAAS(AssetAdministrationShell aas) {
+		String id = aas.getIdentification().getId();
+		this.setAASId(id);
+		
+		Query hasId = query(where(AASIDPATH).is(aasId));
+		// Try to replace if already present - otherwise: insert it
+		Object replaced = mongoOps.findAndReplace(hasId, aas, collection);
+		if (replaced == null) {
+			mongoOps.insert(aas, collection);
+		}
+	}
+
+	@Override
+	public IAssetAdministrationShell getAAS() {
+		Query hasId = query(where(AASIDPATH).is(aasId));
+		AssetAdministrationShell aas = mongoOps.findOne(hasId, AssetAdministrationShell.class, collection);
+		if (aas == null) {
+			throw new ResourceNotFoundException("The AAS " + aasId + " could not be found in the database.");
+		}
+		// Remove mongoDB-specific map attribute from AASDescriptor
+		aas.remove("_id");
+		return aas;
+	}
+
+	@Override
+	public void addSubmodel(IReference submodel) {
+		// Get AAS from db
+		Query hasId = query(where(AASIDPATH).is(aasId));
+		AssetAdministrationShell aas = mongoOps.findOne(hasId, AssetAdministrationShell.class, collection);
+		if (aas == null) {
+			throw new ResourceNotFoundException("The AAS " + aasId + " could not be found in the database.");
+		}
+		// Add reference
+		aas.addSubmodelReference(submodel);
+		// Update db entry
+		mongoOps.findAndReplace(hasId, aas, collection);
+	}
+
+	@Override
+	public void removeSubmodel(String id) {
+		// Get AAS from db
+		Query hasId = query(where(AASIDPATH).is(aasId));
+		AssetAdministrationShell aas = mongoOps.findOne(hasId, AssetAdministrationShell.class, collection);
+		if (aas == null) {
+			throw new ResourceNotFoundException("The AAS " + aasId + " could not be found in the database.");
+		}
+		// Remove reference
+		Collection<IReference> smReferences = aas.getSubmodelReferences();
+		// Reference to submodel could be either by idShort (=> local) or directly via
+		// its identifier
+		for (Iterator<IReference> iterator = smReferences.iterator(); iterator.hasNext();) {
+			IReference ref = iterator.next();
+			List<IKey> keys = ref.getKeys();
+			IKey lastKey = keys.get(keys.size() - 1);
+			String idValue = lastKey.getValue();
+			// remove this reference, if the last key points to the submodel
+			if (idValue.equals(id)) {
+				iterator.remove();
+				break;
+			}
+		}
+		// Update db entry
+		mongoOps.findAndReplace(hasId, aas, collection);
+	}
+
+}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/mongodb/MongoDBAASAggregator.java b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/mongodb/MongoDBAASAggregator.java
new file mode 100644
index 0000000..4d3ead9
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/mongodb/MongoDBAASAggregator.java
@@ -0,0 +1,286 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.components.aas.mongodb;
+
+import static org.springframework.data.mongodb.core.query.Criteria.where;
+import static org.springframework.data.mongodb.core.query.Query.query;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import org.eclipse.basyx.aas.aggregator.AASAggregator;
+import org.eclipse.basyx.aas.aggregator.api.IAASAggregator;
+import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
+import org.eclipse.basyx.aas.restapi.AASModelProvider;
+import org.eclipse.basyx.aas.restapi.MultiSubmodelProvider;
+import org.eclipse.basyx.aas.restapi.api.IAASAPI;
+import org.eclipse.basyx.aas.restapi.api.IAASAPIFactory;
+import org.eclipse.basyx.components.configuration.BaSyxMongoDBConfiguration;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.submodel.metamodel.api.reference.IKey;
+import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyType;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Identifiable;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
+import org.eclipse.basyx.submodel.restapi.SubmodelProvider;
+import org.eclipse.basyx.submodel.restapi.api.ISubmodelAPI;
+import org.eclipse.basyx.submodel.restapi.api.ISubmodelAPIFactory;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
+import org.eclipse.basyx.vab.protocol.api.IConnectorFactory;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.data.mongodb.core.MongoOperations;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.data.mongodb.core.query.Query;
+
+import com.mongodb.client.MongoClient;
+import com.mongodb.client.MongoClients;
+
+/**
+ * An IAASAggregator for persistent storage in a MongoDB.
+ * 
+ * @see AASAggregator AASAggregator for the "InMemory"-variant
+ * 
+ * @author espen
+ *
+ */
+public class MongoDBAASAggregator implements IAASAggregator {
+	private static Logger logger = LoggerFactory.getLogger(MongoDBAASAggregator.class);
+
+	private static final String DEFAULT_CONFIG_PATH = "mongodb.properties";
+	private static final String IDSHORTPATH = Referable.IDSHORT;
+	private static final String IDPATH = Identifiable.IDENTIFICATION + "." + Identifier.ID;
+
+	protected Map<String, MultiSubmodelProvider> aasProviderMap = new HashMap<>();
+	protected BaSyxMongoDBConfiguration config;
+	protected MongoOperations mongoOps;
+	protected String aasCollection;
+	protected String smCollection;
+
+	private IAASRegistry registry;
+
+	/**
+	 * Store AAS API Provider. By default, uses the MongoDB API Provider
+	 */
+	protected IAASAPIFactory aasApiProvider;
+
+	/**
+	 * Store Submodel API Provider. By default, uses a MongoDB Submodel Provider
+	 */
+	protected ISubmodelAPIFactory smApiProvider;
+
+	/**
+	 * Receives the path of the configuration.properties file in it's constructor.
+	 * 
+	 * @param configFilePath
+	 */
+	public MongoDBAASAggregator(BaSyxMongoDBConfiguration config) {
+		this.setConfiguration(config);
+		init();
+	}
+
+	public void setRegistry(IAASRegistry registry) {
+		this.registry = registry;
+	}
+
+	/**
+	 * Receives the path of the .properties file in it's constructor from a resource.
+	 */
+	public MongoDBAASAggregator(String resourceConfigPath) {
+		config = new BaSyxMongoDBConfiguration();
+		config.loadFromResource(resourceConfigPath);
+		this.setConfiguration(config);
+		init();
+	}
+
+	/**
+	 * Constructor using default connections
+	 */
+	public MongoDBAASAggregator() {
+		this(DEFAULT_CONFIG_PATH);
+	}
+
+	/**
+	 * Sets the db configuration for this Aggregator.
+	 * 
+	 * @param config
+	 */
+	public void setConfiguration(BaSyxMongoDBConfiguration config) {
+		// set mongoDB configuration
+		this.config = config;
+		MongoClient client = MongoClients.create(config.getConnectionUrl());
+		this.mongoOps = new MongoTemplate(client, config.getDatabase());
+		this.aasCollection = config.getAASCollection();
+		this.smCollection = config.getSubmodelCollection();
+
+		// Create API factories with the given configuration
+		this.aasApiProvider = aas -> {
+			MongoDBAASAPI api = new MongoDBAASAPI(config, aas.getIdentification().getId());
+			api.setAAS(aas);
+			return api;
+		};
+		this.smApiProvider = sm -> {
+			MongoDBSubmodelAPI api = new MongoDBSubmodelAPI(config, sm.getIdentification().getId());
+			api.setSubmodel(sm);
+			return api;
+		};
+	}
+
+	/**
+	 * Removes all persistent AAS and submodels
+	 */
+	public void reset() {
+		mongoOps.dropCollection(aasCollection);
+		mongoOps.dropCollection(smCollection);
+		aasProviderMap.clear();
+	}
+
+	private void init() {
+		List<AssetAdministrationShell> data = mongoOps.findAll(AssetAdministrationShell.class, aasCollection);
+		for (AssetAdministrationShell aas : data) {
+			String aasId = aas.getIdentification().getId();
+			logger.info("Adding AAS from DB: " + aasId);
+			MongoDBAASAPI aasApi = new MongoDBAASAPI(config, aasId);
+			MultiSubmodelProvider provider = initMultiSubmodelProvider(aasApi);
+			addSubmodelsFromDB(provider, aas);
+			aasProviderMap.put(aas.getIdentification().getId(), provider);
+		}
+	}
+
+	/**
+	 * Initializes and returns a VABMultiSubmodelProvider with only the AssetAdministrationShell
+	 */
+	private MultiSubmodelProvider initMultiSubmodelProvider(IAASAPI aasApi) {
+		AASModelProvider aasProvider = new AASModelProvider(aasApi);
+		IConnectorFactory connProvider = new HTTPConnectorFactory();
+		MultiSubmodelProvider provider = new MultiSubmodelProvider(aasProvider, registry, connProvider,
+				smApiProvider, aasApiProvider);
+		provider.setAssetAdministrationShell(aasProvider);
+		return provider;
+	}
+
+	/**
+	 * Adds submodel providers for submodels in the MongoDB
+	 */
+	private void addSubmodelsFromDB(MultiSubmodelProvider provider, AssetAdministrationShell aas) {
+		// Get ids and idShorts from aas
+		Collection<IReference> submodelRefs = aas.getSubmodelReferences();
+		List<String> smIds = new ArrayList<>();
+		List<String> smIdShorts = new ArrayList<>();
+		for (IReference ref : submodelRefs) {
+			List<IKey> keys = ref.getKeys();
+			IKey lastKey = keys.get(keys.size() - 1);
+			if (lastKey.getIdType() == KeyType.IDSHORT) {
+				smIdShorts.add(lastKey.getValue());
+			} else {
+				smIds.add(lastKey.getValue());
+			}
+		}
+
+		// Add submodel ids by id shorts
+		for (String idShort : smIdShorts) {
+			String id = getSubmodelId(idShort);
+			if (id != null) {
+				smIds.add(id);
+			}
+		}
+
+		// Create a provider for each submodel
+		for (String id : smIds) {
+			logger.info("Adding Submodel from DB: " + id);
+			addSubmodelProvidersById(id, provider);
+		}
+	}
+
+	private String getSubmodelId(String idShort) {
+		Submodel sm = mongoOps.findOne(query(where(IDSHORTPATH).is(idShort)), Submodel.class);
+		if ( sm != null ) {
+			return sm.getIdentification().getId();
+		}
+		return null;
+	}
+
+	private void addSubmodelProvidersById(String smId, MultiSubmodelProvider provider) {
+		ISubmodelAPI smApi = new MongoDBSubmodelAPI(smId);
+		SubmodelProvider smProvider = new SubmodelProvider(smApi);
+		provider.addSubmodel(smProvider);
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public Collection<IAssetAdministrationShell> getAASList() {
+		return aasProviderMap.values().stream().map(p -> {
+			try {
+				return p.getValue("/aas");
+			} catch (Exception e1) {
+				e1.printStackTrace();
+				throw new RuntimeException();
+			}
+		}).map(m -> {
+			AssetAdministrationShell aas = new AssetAdministrationShell();
+			aas.putAll((Map<? extends String, ? extends Object>) m);
+			return aas;
+		}).collect(Collectors.toList());
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public IAssetAdministrationShell getAAS(IIdentifier aasId) {
+		IModelProvider aasProvider = getAASProvider(aasId);
+
+		// get all Elements from provider
+		Map<String, Object> aasMap = (Map<String, Object>) aasProvider.getValue("/aas");
+		return AssetAdministrationShell.createAsFacade(aasMap);
+	}
+
+	@Override
+	public void createAAS(AssetAdministrationShell aas) {
+		IAASAPI aasApi = this.aasApiProvider.getAASApi(aas);
+		MultiSubmodelProvider provider = initMultiSubmodelProvider(aasApi);
+		aasProviderMap.put(aas.getIdentification().getId(), provider);
+	}
+
+	@Override
+	public void updateAAS(AssetAdministrationShell aas) {
+		createAAS(aas);
+	}
+
+	@Override
+	public void deleteAAS(IIdentifier aasId) {
+		Query hasId = query(where(IDPATH).is(aasId));
+		mongoOps.remove(hasId, aasCollection);
+		aasProviderMap.remove(aasId.getId());
+	}
+
+	public MultiSubmodelProvider getProviderForAASId(String aasId) {
+		return aasProviderMap.get(aasId);
+	}
+
+	@Override
+	public IModelProvider getAASProvider(IIdentifier aasId) {
+		MultiSubmodelProvider provider = aasProviderMap.get(aasId.getId());
+
+		if (provider == null) {
+			throw new ResourceNotFoundException("AAS with Id " + aasId.getId() + " does not exist");
+		}
+
+		return provider;
+	}
+}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/mongodb/MongoDBSubmodelAPI.java b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/mongodb/MongoDBSubmodelAPI.java
new file mode 100644
index 0000000..bdc4b53
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/mongodb/MongoDBSubmodelAPI.java
@@ -0,0 +1,428 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.components.aas.mongodb;
+
+import static org.springframework.data.mongodb.core.query.Criteria.where;
+import static org.springframework.data.mongodb.core.query.Query.query;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.eclipse.basyx.components.configuration.BaSyxMongoDBConfiguration;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperation;
+import org.eclipse.basyx.submodel.metamodel.facade.submodelelement.SubmodelElementFacadeFactory;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Identifiable;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
+import org.eclipse.basyx.submodel.restapi.api.ISubmodelAPI;
+import org.eclipse.basyx.vab.exception.provider.MalformedRequestException;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.eclipse.basyx.vab.modelprovider.VABPathTools;
+import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
+import org.eclipse.basyx.vab.modelprovider.map.VABMapProvider;
+import org.springframework.data.mongodb.core.MongoOperations;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.data.mongodb.core.query.Query;
+
+import com.mongodb.client.MongoClient;
+import com.mongodb.client.MongoClients;
+
+/**
+ * Implements the ISubmodelAPI for a mongoDB backend.
+ * 
+ * @author espen
+ */
+public class MongoDBSubmodelAPI implements ISubmodelAPI {
+	private static final String DEFAULT_CONFIG_PATH = "mongodb.properties";
+	private static final String SMIDPATH = Identifiable.IDENTIFICATION + "." + Identifier.ID;
+
+	protected BaSyxMongoDBConfiguration config;
+	protected MongoOperations mongoOps;
+	protected String collection;
+	protected String smId;
+
+	/**
+	 * Receives the path of the configuration.properties file in it's constructor.
+	 * 
+	 * @param configFilePath
+	 */
+	public MongoDBSubmodelAPI(BaSyxMongoDBConfiguration config, String smId) {
+		this.setConfiguration(config);
+		this.setSubmodelId(smId);
+	}
+
+	/**
+	 * Receives the path of the .properties file in it's constructor from a resource.
+	 */
+	public MongoDBSubmodelAPI(String resourceConfigPath, String smId) {
+		config = new BaSyxMongoDBConfiguration();
+		config.loadFromResource(resourceConfigPath);
+		this.setConfiguration(config);
+		this.setSubmodelId(smId);
+	}
+
+	/**
+	 * Constructor using default sql connections
+	 */
+	public MongoDBSubmodelAPI(String smId) {
+		this(DEFAULT_CONFIG_PATH, smId);
+	}
+
+	/**
+	 * Sets the db configuration for the submodel API.
+	 * 
+	 * @param config
+	 */
+	public void setConfiguration(BaSyxMongoDBConfiguration config) {
+		this.config = config;
+		MongoClient client = MongoClients.create(config.getConnectionUrl());
+		this.mongoOps = new MongoTemplate(client, config.getDatabase());
+		this.collection = config.getSubmodelCollection();
+	}
+	
+	/**
+	 * Sets the submodel id, so that this API points to the submodel with smId. Can be changed
+	 * to point to a different submodel in the database.
+	 * 
+	 * @param smId
+	 */
+	public void setSubmodelId(String smId) {
+		this.smId = smId;
+	}
+
+	/**
+	 * Depending on whether the model is already in the db, this method inserts or replaces the existing data.
+	 * The new submodel id for this API is taken from the given submodel.
+	 * 
+	 * @param sm
+	 */
+	public void setSubmodel(Submodel sm) {
+		String id = sm.getIdentification().getId();
+		this.setSubmodelId(id);
+
+		Query hasId = query(where(SMIDPATH).is(smId));
+		Object replaced = mongoOps.findAndReplace(hasId, sm, collection);
+		if (replaced == null) {
+			mongoOps.insert(sm, collection);
+		}
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public ISubmodel getSubmodel() {
+		// Query Submodel from MongoDB
+		Query hasId = query(where(SMIDPATH).is(smId));
+		Submodel result = mongoOps.findOne(hasId, Submodel.class, collection);
+		if (result == null) {
+			throw new ResourceNotFoundException("The submodel " + smId + " could not be found in the database.");
+		}
+
+		// Remove mongoDB-specific map attribute from AASDescriptor
+		result.remove("_id");
+
+		// Cast all SubmodelElement maps to ISubmodelElements before returning the submodel
+		Map<String, ISubmodelElement> elements = new HashMap<>();
+		Map<String, Map<String, Object>> elemMaps = (Map<String, Map<String, Object>>) result
+				.get(Submodel.SUBMODELELEMENT);
+		for (Entry<String, Map<String, Object>> entry : elemMaps.entrySet()) {
+			String shortId = entry.getKey();
+			Map<String, Object> elemMap = entry.getValue();
+			ISubmodelElement element = SubmodelElementFacadeFactory.createSubmodelElement(elemMap);
+			elements.put(shortId, element);
+		}
+		// Replace the element map in the submodel
+		result.put(Submodel.SUBMODELELEMENT, elements);
+		// Return the "fixed" submodel
+		return result;
+	}
+
+	@Override
+	public void addSubmodelElement(ISubmodelElement elem) {
+		// Get sm from db
+		Submodel sm = (Submodel) getSubmodel();
+		// Add element
+		sm.addSubmodelElement(elem);
+		// Replace db entry
+		Query hasId = query(where(SMIDPATH).is(smId));
+		mongoOps.findAndReplace(hasId, sm, collection);
+	}
+
+	private ISubmodelElement getTopLevelSubmodelElement(String idShort) {
+		Submodel sm = (Submodel) getSubmodel();
+		Map<String, ISubmodelElement> submodelElements = sm.getSubmodelElements();
+		ISubmodelElement element = submodelElements.get(idShort);
+		if (element == null) {
+			throw new ResourceNotFoundException("The element \"" + idShort + "\" could not be found");
+		}
+		return convertSubmodelElement(element);
+	}
+
+	@SuppressWarnings("unchecked")
+	private ISubmodelElement convertSubmodelElement(ISubmodelElement element) {
+		// FIXME: Convert internal data structure of ISubmodelElement
+		Map<String, Object> elementMap = (Map<String, Object>) element;
+		IModelProvider elementProvider = new SubmodelElementProvider(new VABMapProvider(elementMap));
+		Object elementVABObj = elementProvider.getValue("");
+		return SubmodelElement.createAsFacade((Map<String, Object>) elementVABObj);
+	}
+
+	private void deleteTopLevelSubmodelElement(String idShort) {
+		// Get sm from db
+		Submodel sm = (Submodel) getSubmodel();
+		// Remove element
+		sm.getSubmodelElements().remove(idShort);
+		// Replace db entry
+		Query hasId = query(where(SMIDPATH).is(smId));
+		mongoOps.findAndReplace(hasId, sm, collection);
+	}
+
+	@Override
+	public Collection<IOperation> getOperations() {
+		Submodel sm = (Submodel) getSubmodel();
+		return sm.getOperations().values();
+	}
+
+
+	private void addNestedSubmodelElement(List<String> idShorts, ISubmodelElement elem) {
+		Submodel sm = (Submodel) getSubmodel();
+		// > 1 idShorts => add new sm element to an existing sm element
+		if (idShorts.size() > 1) {
+			idShorts = idShorts.subList(0, idShorts.size() - 1);
+			// Get parent SM element if more than 1 idShort
+			ISubmodelElement parentElement = getNestedSubmodelElement(sm, idShorts);
+			if (parentElement instanceof SubmodelElementCollection) {
+				((SubmodelElementCollection) parentElement).addSubmodelElement(elem);
+				// Replace db entry
+				Query hasId = query(where(SMIDPATH).is(smId));
+				mongoOps.findAndReplace(hasId, sm, collection);
+			}
+		} else {
+			// else => directly add it to the submodel
+			sm.addSubmodelElement(elem);
+			// Replace db entry
+			Query hasId = query(where(SMIDPATH).is(smId));
+			mongoOps.findAndReplace(hasId, sm, collection);
+		}
+	}
+
+	@Override
+	public Collection<ISubmodelElement> getSubmodelElements() {
+		Submodel sm = (Submodel) getSubmodel();
+		return sm.getSubmodelElements().values();
+	}
+
+	private void updateTopLevelSubmodelElement(String idShort, Object newValue) {
+		// Get sm from db
+		Submodel sm = (Submodel) getSubmodel();
+		// Unwrap value
+		newValue = unwrapParameter(newValue);
+		// Get and update property value
+		getElementProvider(sm, idShort).setValue(Property.VALUE, newValue);
+		// Replace db entry
+		Query hasId = query(where(SMIDPATH).is(smId));
+		mongoOps.findAndReplace(hasId, sm, collection);
+	}
+
+	@SuppressWarnings("unchecked")
+	private void updateNestedSubmodelElement(List<String> idShorts, Object newValue) {
+		Submodel sm = (Submodel) getSubmodel();
+
+		// Get parent SM element
+		ISubmodelElement element = getNestedSubmodelElement(sm, idShorts);
+
+		// Update value
+		IModelProvider mapProvider = new VABMapProvider((Map<String, Object>) element);
+		IModelProvider elemProvider = SubmodelElementProvider.getElementProvider(mapProvider);
+		elemProvider.setValue(Property.VALUE, newValue);
+
+		// Replace db entry
+		Query hasId = query(where(SMIDPATH).is(smId));
+		mongoOps.findAndReplace(hasId, sm, collection);
+	}
+
+	private Object getTopLevelSubmodelElementValue(String idShort) {
+		Submodel sm = (Submodel) getSubmodel();
+		return getElementProvider(sm, idShort).getValue("/value");
+	}
+
+	@SuppressWarnings("unchecked")
+	private Object getNestedSubmodelElementValue(List<String> idShorts) {
+		ISubmodelElement lastElement = getNestedSubmodelElement(idShorts);
+		IModelProvider mapProvider = new VABMapProvider((Map<String, Object>) lastElement);
+		return SubmodelElementProvider.getElementProvider(mapProvider).getValue("/value");
+	}
+
+	@SuppressWarnings("unchecked")
+	protected Object unwrapParameter(Object parameter) {
+		if (parameter instanceof Map<?, ?>) {
+			Map<String, Object> map = (Map<String, Object>) parameter;
+			// Parameters have a strictly defined order and may not be omitted at all.
+			// Enforcing the structure with valueType is ok, but we should unwrap null values, too.
+			if (map.get("valueType") != null && map.containsKey("value")) {
+				return map.get("value");
+			}
+		}
+		return parameter;
+	}
+
+	@SuppressWarnings("unchecked")
+	private IModelProvider getElementProvider(Submodel sm, String idShort) {
+		ISubmodelElement elem = sm.getSubmodelElements().get(idShort);
+		IModelProvider mapProvider = new VABMapProvider((Map<String, Object>) elem);
+		return SubmodelElementProvider.getElementProvider(mapProvider);
+	}
+
+	private ISubmodelElement getNestedSubmodelElement(Submodel sm, List<String> idShorts) {
+		Map<String, ISubmodelElement> elemMap = sm.getSubmodelElements();
+		// Get last nested submodel element
+		for (int i = 0; i < idShorts.size() - 1; i++) {
+			String idShort = idShorts.get(i);
+			ISubmodelElement elem = elemMap.get(idShort);
+			if (elem instanceof SubmodelElementCollection) {
+				elemMap = ((SubmodelElementCollection) elem).getSubmodelElements();
+			} else {
+				throw new ResourceNotFoundException(
+						idShort + " in the nested submodel element path could not be resolved.");
+			}
+		}
+		String lastIdShort = idShorts.get(idShorts.size() - 1);
+		if (!elemMap.containsKey(lastIdShort)) {
+			throw new ResourceNotFoundException(lastIdShort
+					+ " in the nested submodel element path could not be resolved.");
+		}
+		return elemMap.get(lastIdShort);
+	}
+
+	private ISubmodelElement getNestedSubmodelElement(List<String> idShorts) {
+		// Get sm from db
+		Submodel sm = (Submodel) getSubmodel();
+		// Get nested sm element from this sm
+		return convertSubmodelElement(getNestedSubmodelElement(sm, idShorts));
+	}
+
+	private Object invokeTopLevelOperation(String idShort, Object... params) {
+		// not possible to invoke operations on a submodel that is stored in a db
+		throw new MalformedRequestException("Invoke not supported by this backend");
+	}
+
+	private void deleteNestedSubmodelElement(List<String> idShorts) {
+		if ( idShorts.size() == 1 ) {
+			deleteSubmodelElement(idShorts.get(0));
+			return;
+		}
+		
+		// Get sm from db
+		Submodel sm = (Submodel) getSubmodel();
+		// Get parent collection
+		List<String> parentIds = idShorts.subList(0, idShorts.size() - 1);
+		ISubmodelElement parentElement = getNestedSubmodelElement(sm, parentIds);
+		// Remove element
+		SubmodelElementCollection coll = (SubmodelElementCollection) parentElement;
+		coll.deleteSubmodelElement(idShorts.get(idShorts.size() - 1));
+		// Replace db entry
+		Query hasId = query(where(SMIDPATH).is(smId));
+		mongoOps.findAndReplace(hasId, sm, collection);
+	}
+
+	private Object invokeNestedOperation(List<String> idShorts, Object... params) {
+		// not possible to invoke operations on a submodel that is stored in a db
+		throw new MalformedRequestException("Invoke not supported by this backend");
+	}
+
+	private Object invokeNestedOperationAsync(List<String> idShorts, Object... params) {
+		// not possible to invoke operations on a submodel that is stored in a db
+		throw new MalformedRequestException("Invoke not supported by this backend");
+	}
+
+	@Override
+	public Object getOperationResult(String idShort, String requestId) {
+		// not possible to invoke operations on a submodel that is stored in a db
+		throw new MalformedRequestException("Invoke not supported by this backend");
+	}
+
+	@Override
+	public ISubmodelElement getSubmodelElement(String idShortPath) {
+		if(idShortPath.contains("/")) {
+			String[] splitted = VABPathTools.splitPath(idShortPath);
+			List<String> idShorts = Arrays.asList(splitted);
+			return getNestedSubmodelElement(idShorts);
+		}else {
+			return getTopLevelSubmodelElement(idShortPath);
+		}
+	}
+
+	@Override
+	public void deleteSubmodelElement(String idShortPath) {
+		if(idShortPath.contains("/")) {
+			String[] splitted = VABPathTools.splitPath(idShortPath);
+			List<String> idShorts = Arrays.asList(splitted);
+			deleteNestedSubmodelElement(idShorts);
+		}else {
+			deleteTopLevelSubmodelElement(idShortPath);
+		}
+	}
+
+	@Override
+	public void updateSubmodelElement(String idShortPath, Object newValue) {
+		if(idShortPath.contains("/")) {
+			String[] splitted = VABPathTools.splitPath(idShortPath);
+			List<String> idShorts = Arrays.asList(splitted);
+			updateNestedSubmodelElement(idShorts, newValue);
+		}else {
+			updateTopLevelSubmodelElement(idShortPath, newValue);
+		}
+	}
+
+	@Override
+	public Object getSubmodelElementValue(String idShortPath) {
+		if(idShortPath.contains("/")) {
+			String[] splitted = VABPathTools.splitPath(idShortPath);
+			List<String> idShorts = Arrays.asList(splitted);
+			return getNestedSubmodelElementValue(idShorts);
+		}else {
+			return getTopLevelSubmodelElementValue(idShortPath);
+		}
+	}
+
+	@Override
+	public Object invokeOperation(String idShortPath, Object... params) {
+		if(idShortPath.contains("/")) {
+			String[] splitted = VABPathTools.splitPath(idShortPath);
+			List<String> idShorts = Arrays.asList(splitted);
+			return invokeNestedOperation(idShorts, params);
+		}else {
+			return invokeTopLevelOperation(idShortPath, params);
+		}
+	}
+
+	@Override
+	public Object invokeAsync(String idShortPath, Object... params) {
+		String[] splitted = VABPathTools.splitPath(idShortPath);
+		List<String> idShorts = Arrays.asList(splitted);
+		return invokeNestedOperationAsync(idShorts, params);
+	}
+
+	@Override
+	public void addSubmodelElement(String idShortPath, ISubmodelElement elem) {
+		String[] splitted = VABPathTools.splitPath(idShortPath);
+		List<String> idShorts = Arrays.asList(splitted);
+		addNestedSubmodelElement(idShorts, elem);
+	}
+}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/mqtt/MqttSubmodelAPIFactory.java b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/mqtt/MqttSubmodelAPIFactory.java
new file mode 100644
index 0000000..742e033
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/mqtt/MqttSubmodelAPIFactory.java
@@ -0,0 +1,88 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.components.aas.mqtt;
+
+import java.util.Set;
+
+import org.eclipse.basyx.components.configuration.BaSyxMqttConfiguration;
+import org.eclipse.basyx.extensions.submodel.mqtt.MqttSubmodelAPI;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.restapi.api.ISubmodelAPI;
+import org.eclipse.basyx.submodel.restapi.api.ISubmodelAPIFactory;
+import org.eclipse.basyx.submodel.restapi.vab.VABSubmodelAPI;
+import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
+import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaProvider;
+import org.eclipse.paho.client.mqttv3.MqttException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Api provider for constructing a new Submodel API that emits MQTT events
+ * 
+ * @author espen
+ */
+public class MqttSubmodelAPIFactory implements ISubmodelAPIFactory {
+	private static Logger logger = LoggerFactory.getLogger(MqttSubmodelAPIFactory.class);
+
+	private BaSyxMqttConfiguration config;
+
+	/**
+	 * Constructor with MQTT configuration for providing submodel APIs
+	 * 
+	 * @param config
+	 */
+	public MqttSubmodelAPIFactory(BaSyxMqttConfiguration config) {
+		this.config = config;
+	}
+
+	@Override
+	public ISubmodelAPI getSubmodelAPI(Submodel sm) {
+		// Get the submodel's id from the given provider
+		String smId = sm.getIdentification().getId();
+		
+		// Create the API
+		IModelProvider provider = new VABLambdaProvider(sm);
+		VABSubmodelAPI observedApi = new VABSubmodelAPI(provider);
+
+		// Configure the API according to the given configs
+		String brokerEndpoint = config.getServer();
+		String clientId = smId;
+		MqttSubmodelAPI api;
+		try {
+			if (config.getUser() != null) {
+				String user = config.getUser();
+				String pass = config.getPass();
+				api = new MqttSubmodelAPI(observedApi, brokerEndpoint, clientId, user, pass.toCharArray());
+			} else {
+				api = new MqttSubmodelAPI(observedApi, brokerEndpoint, clientId);
+			}
+			setWhitelist(api, smId);
+		} catch (MqttException e) {
+			logger.error("Could not create MqttSubmodelApi", e);
+			return observedApi;
+		}
+		return api;
+	}
+
+	private void setWhitelist(MqttSubmodelAPI api, String smId) {
+		if (!config.isWhitelistEnabled(smId)) {
+			// Do not use the whitelist if it has been disabled
+			api.disableWhitelist();
+			return;
+		}
+
+		// Read whitelist from configuration
+		Set<String> whitelist = config.getWhitelist(smId);
+
+		logger.info("Set MQTT whitelist for " + smId + " with " + whitelist.size() + " entries");
+		api.setWhitelist(whitelist);
+		api.enableWhitelist();
+	}
+}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/servlet/AASAggregatorServlet.java b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/servlet/AASAggregatorServlet.java
new file mode 100644
index 0000000..d3c7a17
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/servlet/AASAggregatorServlet.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.components.aas.servlet;
+
+import org.eclipse.basyx.aas.aggregator.AASAggregator;
+import org.eclipse.basyx.aas.aggregator.api.IAASAggregator;
+import org.eclipse.basyx.aas.aggregator.restapi.AASAggregatorProvider;
+import org.eclipse.basyx.vab.protocol.http.server.VABHTTPInterface;
+
+/**
+ * A servlet containing the empty infrastructure needed to support receiving
+ * AAS/Submodels by clients and hosting them
+ * 
+ * @author schnicke
+ *
+ */
+public class AASAggregatorServlet extends VABHTTPInterface<AASAggregatorProvider> {
+	private static final long serialVersionUID = 1244938902937878401L;
+
+	public AASAggregatorServlet() {
+		super(new AASAggregatorProvider(new AASAggregator()));
+	}
+
+	public AASAggregatorServlet(IAASAggregator aggregator) {
+		super(new AASAggregatorProvider(aggregator));
+	}
+}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/resources/aas.properties b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/resources/aas.properties
new file mode 100644
index 0000000..5fb6126
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/resources/aas.properties
@@ -0,0 +1,45 @@
+# #############################
+# AAS Server configuration file
+# #############################
+
+# #############################
+# Backend
+# #############################
+# Specifies the backend that loads the AAS and Submodels 
+
+# InMemory - does not persist AAS or submodels 
+aas.backend=InMemory
+
+# MongoDB - persists data within a MongoDB
+# See connection configuration in mongodb.properties
+# aas.backend=MongoDB
+
+# #############################
+# Source
+# #############################
+# Possible to load an AAS Environment from a file
+
+aas.source=
+
+# Other examples (Currently supported: *.xml, *.json and  *.aasx): 
+# aas.source=aasx/myAAS.aasx
+# aas.source=aasx/myAAS.xml
+# aas.source=aasx/myAAS.json
+# Or when encapsulated in the docker volume for this container:
+# aas.source=/usr/share/config/myAAS.aasx
+
+# #############################
+# MQTT
+# #############################
+# Possible to enable MQTT events
+
+aas.events=NONE
+# aas.events=MQTT
+
+
+# #############################
+# Registry
+# #############################
+# If specified, can directly registers the AAS that has been loaded from the source file
+
+# registry.path=http://localhost:4000/registry/
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASX/src/main/resources/aasx/01_Festo.aasx b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/resources/aasx/01_Festo.aasx
similarity index 100%
rename from components/basys.components/basyx.components.docker/basyx.components.AASX/src/main/resources/aasx/01_Festo.aasx
rename to components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/resources/aasx/01_Festo.aasx
Binary files differ
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/resources/context.properties b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/resources/context.properties
index a723466..65f2a94 100644
--- a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/resources/context.properties
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/resources/context.properties
@@ -1,3 +1,24 @@
+# ###############################
+# HTTP Context configuration file
+# ###############################
+
+# ###############################
+# Context Path
+# ###############################
+# Specifies the subpath in the url for this server context
+ 
 contextPath=/aasServer
+
+# ###############################
+# Hostname
+# ###############################
+# Specifies the hostname for this server context
+
 contextHostname=localhost
-contextPort=4000
\ No newline at end of file
+
+# ###############################
+# Port
+# ###############################
+# Specifies the port for this server context
+
+contextPort=4001
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/resources/json/aas.json b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/resources/json/aas.json
new file mode 100644
index 0000000..afa70e0
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/resources/json/aas.json
@@ -0,0 +1,570 @@
+{
+  "assetAdministrationShells": [
+    {
+      "asset": {
+        "keys": [
+          {
+            "type": "Asset",
+            "local": true,
+            "value": "http://customer.com/assets/KHBVZJSQKIY",
+            "idType": "IRI"
+          }
+        ],
+        "kind": "Type",
+        "idShort": "assetId1",
+        "identification": {
+        	"idType": "IRI",
+        	"id": "assetId1"
+        }
+      },
+      "submodels": [
+        {
+          "keys": [
+            {
+              "type": "Submodel",
+              "local": true,
+              "value": "http.//i40.customer.com/type/1/1/7A7104BDAB57E184",
+              "idType": "IRI"
+            }
+          ],
+          "idShort": "submodelId1",
+	      "identification": {
+	      	  "idType": "IRI",
+	          "id": "submodelId1"
+	      }
+        },
+        {
+          "keys": [
+            {
+              "type": "Submodel",
+              "local": true,
+              "value": "http://i40.customer.com/instance/1/1/AC69B1CB44F07935",
+              "idType": "IRI"
+            }
+          ],
+          "idShort": "submodelId2",
+	      "identification": {
+	      	  "idType": "IRI",
+	          "id": "submodelId2"
+	      }
+        },
+        {
+          "keys": [
+            {
+              "type": "Submodel",
+              "local": true,
+              "value": "http://i40.customer.com/type/1/1/1A7B62B529F19152",
+              "idType": "IRI"
+            }
+          ],
+          "idShort": "submodelId3",
+	      "identification": {
+	      	  "idType": "IRI",
+	          "id": "submodelId3"
+	      }
+        }
+      ],
+      "conceptDictionaries": [],
+      "identification": {
+        "idType": "IRI",
+        "id": "http://customer.com/aas/9175_7013_7091_9168"
+      },
+      "idShort": "ExampleMotor",
+      "category": "CONSTANT",
+      "modelType": {
+        "name": "AssetAdministrationShell"
+      }
+    }
+  ],
+  "assets": [
+    {
+      "assetIdentificationModelRef": {
+        "keys": [
+          {
+            "type": "Submodel",
+            "local": true,
+            "value": "i40.customer.com/type/1/1/F13E8576F6488342",
+            "idType": "IRI"
+          }
+        ]
+      },
+      "identification": {
+        "idType": "IRI",
+        "id": "http://customer.com/assets/KHBVZJSQKIY"
+      },
+      "idShort": "ServoDCMotor",
+      "category": "",
+      "modelType": {
+        "name": "Asset"
+      },
+      "kind": "Instance"
+    }
+  ],
+  "submodels": [
+    {
+      "semanticId": {
+        "keys": [
+          {
+            "type": "GlobalReference",
+            "local": false,
+            "value": "0173-1#01-AFZ615#016",
+            "idType": "IRDI"
+          }
+        ]
+      },
+      "identification": {
+        "idType": "IRI",
+        "id": "http.//i40.customer.com/type/1/1/7A7104BDAB57E184"
+      },
+      "idShort": "TechnicalData",
+      "category": "CONSTANT",
+      "modelType": {
+        "name": "Submodel"
+      },
+      "kind": "Instance",
+      "submodelElements": [
+        {
+          "value": "5000",
+          "semanticId": {
+            "keys": [
+              {
+                "type": "ConceptDescription",
+                "local": true,
+                "value": "0173-1#02-BAA120#008",
+                "idType": "IRDI"
+              }
+            ]
+          },
+          "constraints": [],
+          "idShort": "MaxRotationSpeed",
+          "category": "PARAMETER",
+          "modelType": {
+            "name": "Property"
+          },
+          "valueType": "integer",
+          "kind": "Instance"
+        }
+      ]
+    },
+    {
+      "semanticId": {
+        "keys": []
+      },
+      "identification": {
+        "idType": "IRI",
+        "id": "http://i40.customer.com/type/1/1/1A7B62B529F19152"
+      },
+      "idShort": "Documentation",
+      "category": "CONSTANT",
+      "modelType": {
+        "name": "Submodel"
+      },
+      "kind": "Instance",
+      "submodelElements": [
+        {
+          "ordered": false,
+          "allowDuplicates": false,
+          "semanticId": {
+            "keys": [
+              {
+                "type": "ConceptDescription",
+                "local": true,
+                "value": "www.vdi2770.com/blatt1/Entwurf/Okt18/cd/Document",
+                "idType": "IRI"
+              }
+            ]
+          },
+          "constraints": [],
+          "idShort": "OperatingManual",
+          "category": "",
+          "modelType": {
+            "name": "SubmodelElementCollection"
+          },
+          "value": [
+            {
+              "value": "Operating Manual",
+              "semanticId": {
+                "keys": [
+                  {
+                    "type": "ConceptDescription",
+                    "local": true,
+                    "value": "www.vdi2770.com/blatt1/Entwurf/Okt18/cd/Description/Title",
+                    "idType": "IRI"
+                  }
+                ]
+              },
+              "constraints": [],
+              "idShort": "Title",
+              "modelType": {
+                "name": "Property"
+              },
+              "valueType": "langString",
+              "kind": "Instance"
+            },
+            {
+              "mimeType": "application/pdf",
+              "value": "/aasx/OperatingManual.pdf",
+              "semanticId": {
+                "keys": [
+                  {
+                    "type": "ConceptDescription",
+                    "local": true,
+                    "value": "www.vdi2770.com/blatt1/Entwurf/Okt18/cd/StoredDocumentRepresentation/DigitalFile",
+                    "idType": "IRI"
+                  }
+                ]
+              },
+              "constraints": [],
+              "idShort": "DigitalFile_PDF",
+              "category": "PARAMETER",
+              "modelType": {
+                "name": "File"
+              },
+              "kind": "Instance"
+            }
+          ],
+          "kind": "Instance"
+        }
+      ]
+    },
+    {
+      "semanticId": {
+        "keys": []
+      },
+      "qualifiers": [],
+      "identification": {
+        "idType": "IRI",
+        "id": "http://i40.customer.com/instance/1/1/AC69B1CB44F07935"
+      },
+      "idShort": "OperationalData",
+      "category": "VARIABLE",
+      "modelType": {
+        "name": "Submodel"
+      },
+      "kind": "Instance",
+      "submodelElements": [
+        {
+          "value": "4370",
+          "hasDataSpecification": {
+            "reference": []
+          },
+          "semanticId": {
+            "keys": [
+              {
+                "type": "ConceptDescription",
+                "local": true,
+                "value": "http://customer.com/cd/1/1/18EBD56F6B43D895",
+                "idType": "IRI"
+              }
+            ]
+          },
+          "constraints": [],
+          "idShort": "RotationSpeed",
+          "category": "VARIABLE",
+          "modelType": {
+            "name": "Property"
+          },
+          "valueType": "integer",
+          "kind": "Instance"
+        }
+      ]
+    }
+  ],
+  "conceptDescriptions": [
+    {
+      "identification": {
+        "idType": "IRI",
+        "id": "www.vdi2770.com/blatt1/Entwurf/Okt18/cd/Description/Title"
+      },
+      "idShort": "Title",
+      "category": "CONSTANT",
+      "modelType": {
+        "name": "ConceptDescription"
+      },
+      "embeddedDataSpecifications": [
+        {
+          "dataSpecification": {
+            "keys": [
+              {
+                "type": "GlobalReference",
+                "local": false,
+                "value": "http://admin-shell.io/DataSpecificationTemplates/DataSpecificationIEC61360",
+                "idType": "IRI"
+              }
+            ]
+          },
+          "dataSpecificationContent": {
+            "preferredName": [
+              {
+                "language": "EN",
+                "text": "Title"
+              },
+              {
+                "language": "DE",
+                "text": "Titel"
+              }
+            ],
+            "shortName": [
+              {
+                "language": "EN",
+                "text": "Title"
+              },
+              {
+                "language": "DE",
+                "text": "Titel"
+              }
+            ],
+            "unit": "",
+            "sourceOfDefinition": "",
+            "dataType": "STRING_TRANSLATABLE",
+            "definition": [
+              {
+                "language": "DE",
+                "text": "Sprachabhängiger Titel des Dokuments."
+              }
+            ]
+          }
+        }
+      ],
+      "isCaseOf": []
+    },
+    {
+      "identification": {
+        "idType": "IRI",
+        "id": "www.vdi2770.com/blatt1/Entwurf/Okt18/cd/StoredDocumentRepresentation/DigitalFile"
+      },
+      "idShort": "DigitalFile",
+      "modelType": {
+        "name": "ConceptDescription"
+      },
+      "embeddedDataSpecifications": [
+        {
+          "dataSpecification": {
+            "keys": [
+              {
+                "type": "GlobalReference",
+                "local": false,
+                "value": "http://admin-shell.io/DataSpecificationTemplates/DataSpecificationIEC61360",
+                "idType": "IRI"
+              }
+            ]
+          },
+          "dataSpecificationContent": {
+            "preferredName": [
+              {
+                "language": "EN",
+                "text": "Digital File"
+              },
+              {
+                "language": "DE",
+                "text": "Digitale Datei"
+              }
+            ],
+            "shortName": [
+              {
+                "language": "EN",
+                "text": "DigitalFile"
+              },
+              {
+                "language": "DE",
+                "text": "DigitaleDatei"
+              }
+            ],
+            "unit": "",
+            "sourceOfDefinition": "",
+            "dataType": "STRING",
+            "definition": [
+              {
+                "language": "DE",
+                "text": "Eine Datei, die die DocumentVersion repräsentiert. Neben der obligatorischen PDF/A Datei können weitere Dateien angegeben werden."
+              }
+            ]
+          }
+        }
+      ],
+      "isCaseOf": []
+    },
+    {
+      "identification": {
+        "idType": "IRDI",
+        "id": "0173-1#02-BAA120#008"
+      },
+      "administration": {
+        "version": "",
+        "revision": "2"
+      },
+      "idShort": "MaxRotationSpeed",
+      "category": "PROPERTY",
+      "modelType": {
+        "name": "ConceptDescription"
+      },
+      "embeddedDataSpecifications": [
+        {
+          "dataSpecification": {
+            "keys": []
+          },
+          "dataSpecificationContent": {
+            "preferredName": [
+              {
+                "language": "de",
+                "text": "max. Drehzahl"
+              },
+              {
+                "language": "en",
+                "text": "Max. rotation speed"
+              }
+            ],
+            "shortName": [],
+            "unit": "1/min",
+            "unitId": {
+              "keys": [
+                {
+                  "type": "GlobalReference",
+                  "local": false,
+                  "value": "0173-1#05-AAA650#002",
+                  "idType": "IRDI"
+                }
+              ]
+            },
+            "sourceOfDefinition": "",
+            "dataType": "REAL_MEASURE",
+            "definition": [
+              {
+                "language": "de",
+                "text": "Höchste zulässige Drehzahl, mit welcher der Motor oder die Speiseinheit betrieben werden darf"
+              },
+              {
+                "language": "en",
+                "text": "Greatest permissible rotation speed with which the motor or feeding unit may be operated"
+              }
+            ]
+          }
+        }
+      ],
+      "isCaseOf": [
+        {
+          "keys": []
+        }
+      ]
+    },
+    {
+      "identification": {
+        "idType": "IRI",
+        "id": "http://customer.com/cd/1/1/18EBD56F6B43D895"
+      },
+      "idShort": "RotationSpeed",
+      "category": "PROPERTY",
+      "modelType": {
+        "name": "ConceptDescription"
+      },
+      "embeddedDataSpecifications": [
+        {
+          "dataSpecification": {
+            "keys": [
+              {
+                "type": "GlobalReference",
+                "local": false,
+                "value": "http://admin-shell.io/DataSpecificationTemplates/DataSpecificationIEC61360",
+                "idType": "IRI"
+              }
+            ]
+          },
+          "dataSpecificationContent": {
+            "preferredName": [
+              {
+                "language": "DE",
+                "text": "Aktuelle Drehzahl"
+              },
+              {
+                "language": "EN",
+                "text": "Actual rotation speed"
+              }
+            ],
+            "shortName": [
+              {
+                "language": "DE",
+                "text": "AktuelleDrehzahl"
+              },
+              {
+                "language": "EN",
+                "text": "ActualRotationSpeed"
+              }
+            ],
+            "unit": "1/min",
+            "unitId": {
+              "keys": [
+                {
+                  "type": "GlobalReference",
+                  "local": false,
+                  "value": "0173-1#05-AAA650#002",
+                  "idType": "IRDI"
+                }
+              ]
+            },
+            "sourceOfDefinition": "",
+            "dataType": "REAL_MEASURE",
+            "definition": [
+              {
+                "language": "DE",
+                "text": "Aktuelle Drehzahl, mit welcher der Motor oder die Speiseinheit betrieben wird"
+              },
+              {
+                "language": "EN",
+                "text": "Actual rotation speed with which the motor or feeding unit is operated"
+              }
+            ]
+          }
+        }
+      ],
+      "isCaseOf": []
+    },
+    {
+      "identification": {
+        "idType": "IRI",
+        "id": "www.vdi2770.com/blatt1/Entwurf/Okt18/cd/Document"
+      },
+      "idShort": "Document",
+      "modelType": {
+        "name": "ConceptDescription"
+      },
+      "embeddedDataSpecifications": [
+        {
+          "dataSpecification": {
+            "keys": [
+              {
+                "type": "GlobalReference",
+                "local": false,
+                "value": "http://admin-shell.io/DataSpecificationTemplates/DataSpecificationIEC61360",
+                "idType": "IRI"
+              }
+            ]
+          },
+          "dataSpecificationContent": {
+            "preferredName": [],
+            "shortName": [
+              {
+                "language": "EN",
+                "text": "Document"
+              },
+              {
+                "language": "DE",
+                "text": "Dokument"
+              }
+            ],
+            "unit": "",
+            "sourceOfDefinition": "[ISO 15519-1:2010]",
+            "dataType": "STRING",
+            "definition": [
+              {
+                "language": "DE",
+                "text": "Feste und geordnete Menge von für die Verwendung durch Personen bestimmte Informationen, die verwaltet und als Einheit zwischen Benutzern und System ausgetauscht werden kann."
+              }
+            ]
+          }
+        }
+      ],
+      "isCaseOf": [],
+      "descriptions": []
+    }
+  ]
+}
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/resources/mongodb.properties b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/resources/mongodb.properties
new file mode 100644
index 0000000..2b3c79d
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/resources/mongodb.properties
@@ -0,0 +1,32 @@
+# #############################
+# MongoDB Backend configuration
+# #############################
+
+# #############################
+# Database Name
+# #############################
+# The database in the MongoDB that hold the data
+
+dbname=admin
+
+# #############################
+# Connection String
+# #############################
+# MongoDB connection string for connecting to the MongoDB endpoint
+
+dbconnectionstring=mongodb://localhost:27017/
+
+# #############################
+# AAS collections
+# #############################
+# Collection names that are used for storing the AAS and Submodels
+
+dbcollectionAAS=assetadministrationshells
+dbcollectionSubmodels=submodels
+
+# #############################
+# Registry Collections
+# #############################
+# Collection name that is used for storing registry data
+
+dbcollectionRegistry=registry
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/resources/mqtt.properties b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/resources/mqtt.properties
new file mode 100644
index 0000000..7762dc9
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/resources/mqtt.properties
@@ -0,0 +1,35 @@
+# ##################
+# MQTT configuration
+# ##################
+
+# ##################
+# Credentials
+# ##################
+# The credentials for connecting to the MQTT broker
+
+# user=
+# pass=
+
+# ##################
+# Server location
+# ##################
+# Broker address to connect to
+
+server=tcp://localhost:1883
+
+# ##################
+# QoS
+# ##################
+# QoS level for the mqtt messages (0, 1 or 2). Default is 1.
+
+# qos=2
+
+# ##################
+# Filtered whitelist
+# ##################
+# Whitelist for filtering mqtt events for specific submodels / submodelelements
+
+whitelist.patientTemplate=true
+whitelist.element.patientTemplate.active=true
+# whitelist.element.{mySmIdentifier}.{elementIdShort}=true
+
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/resources/xml/aas.xml b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/resources/xml/aas.xml
new file mode 100644
index 0000000..2c75def
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/resources/xml/aas.xml
@@ -0,0 +1,586 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<aas:aasenv xmlns:aas="http://www.admin-shell.io/aas/2/0"
+	xmlns:IEC61360="http://www.admin-shell.io/IEC61360/2/0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://www.admin-shell.io/aas/2/0 AAS.xsd
+	http://www.admin-shell.io/IEC61360/2/0 IEC61360.xsd">
+	<aas:assetAdministrationShells>
+		<!-- This AAS is populated with all possible fields -->
+		<aas:assetAdministrationShell>
+			<aas:idShort>aas1</aas:idShort>
+			<aas:category>test_category</aas:category>
+			<aas:description>
+				<aas:langString lang="EN">aas_Description</aas:langString>
+				<aas:langString lang="DE">Beschreibung Verwaltungsschale</aas:langString>
+			</aas:description>
+			<aas:parent>
+				<!-- Parent is currently a String in the Schema. But it should be a Reference. -->
+				<aas:keys>
+					<aas:key idType="IRI" local="false" type="AssetAdministrationShell">aas_parent_id</aas:key>
+				</aas:keys>
+			</aas:parent>
+			<aas:identification idType="IRI">www.admin-shell.io/aas-sample/2/0</aas:identification>
+			<aas:administration>
+				<aas:version>1</aas:version>
+				<aas:revision>0</aas:revision>
+			</aas:administration>
+			<aas:embeddedDataSpecification>
+				<aas:dataSpecificationContent>
+					<aas:dataSpecificationIEC61360>
+						<IEC61360:preferredName>
+							<IEC61360:langString lang="DE">Drehzahl</IEC61360:langString>
+							<IEC61360:langString lang="EN">Rotation Speed</IEC61360:langString>
+						</IEC61360:preferredName>
+						<IEC61360:shortName>
+							<IEC61360:langString lang="DE">N</IEC61360:langString>
+						</IEC61360:shortName>
+						<IEC61360:unit>1/min</IEC61360:unit>
+						<IEC61360:unitId>
+							<IEC61360:keys>
+								<IEC61360:key idType="IRDI" local="false" type="GlobalReference">
+									0173-1#05-AAA650#002
+								</IEC61360:key>
+							</IEC61360:keys>
+						</IEC61360:unitId>
+						<IEC61360:valueFormat>NR1..5</IEC61360:valueFormat>
+					</aas:dataSpecificationIEC61360>
+				</aas:dataSpecificationContent>
+				<aas:dataSpecification>
+					<aas:keys>
+						<aas:key idType="IRI" local="false" type="GlobalReference">www.admin-shell.io/DataSpecificationTemplates/DataSpecificationIEC61360</aas:key>
+					</aas:keys>
+				</aas:dataSpecification>
+			</aas:embeddedDataSpecification>
+			<aas:derivedFrom>
+				<aas:keys>
+					<aas:key type="ReferenceElement" local="false" idType="IRI">http://pk.festo.com/3s7plfdrs35</aas:key>
+				</aas:keys>
+			</aas:derivedFrom>
+			<aas:assetRef>
+				<aas:keys>
+					<aas:key type="Asset" local="false" idType="IRI">http://pk.festo.com/3s7plfdrs35</aas:key>
+				</aas:keys>
+			</aas:assetRef>
+			<aas:submodelRefs>
+				<aas:submodelRef>
+					<aas:keys>
+						<aas:key type="Submodel" local="true" idType="IRI">http://www.zvei.de/demo/submodel/12345679</aas:key>
+					</aas:keys>
+				</aas:submodelRef>
+			</aas:submodelRefs>
+			<aas:views>
+				<!-- This View is populated with all possible fields -->
+				<aas:view>
+					<aas:idShort>SampleView</aas:idShort>
+					<aas:category>test_categogy</aas:category>
+					<aas:description>
+						<aas:langString lang="EN">View_Description</aas:langString>
+					</aas:description>
+					<aas:parent>
+						<!-- Parent is currently a String in the Schema. But it should be a Reference. -->
+						<aas:keys>
+							<aas:key idType="IRI" local="false" type="Submodel">view_parent_id</aas:key>
+						</aas:keys>
+					</aas:parent>
+					<aas:semanticId>
+						<aas:keys>
+							<aas:key idType="IRI" local="false" type="Submodel">view_semantic_id</aas:key>
+						</aas:keys>
+					</aas:semanticId>
+					<aas:embeddedDataSpecification>
+						<aas:dataSpecificationContent>
+							<aas:dataSpecificationIEC61360>
+								<IEC61360:preferredName>
+									<IEC61360:langString lang="DE">Drehzahl</IEC61360:langString>
+									<IEC61360:langString lang="EN">Rotation Speed</IEC61360:langString>
+								</IEC61360:preferredName>
+								<IEC61360:shortName>
+									<IEC61360:langString lang="DE">N</IEC61360:langString>
+								</IEC61360:shortName>
+								<IEC61360:unit>1/min</IEC61360:unit>
+								<IEC61360:unitId>
+									<IEC61360:keys>
+										<IEC61360:key local="false" type="GlobalReference" idType="IRDI">0173-1#05-AAA650#002</IEC61360:key>
+									</IEC61360:keys>
+								</IEC61360:unitId>
+								<IEC61360:valueFormat>NR1..5</IEC61360:valueFormat>
+							</aas:dataSpecificationIEC61360>
+						</aas:dataSpecificationContent>
+						<aas:dataSpecification>
+							<aas:keys>
+								<aas:key idType="IRI" local="false" type="GlobalReference">www.admin-shell.io/DataSpecificationTemplates/DataSpecificationIEC61360</aas:key>
+							</aas:keys>
+						</aas:dataSpecification>
+					</aas:embeddedDataSpecification>
+					<aas:containedElements>
+						<aas:containedElementRef>
+							<aas:keys>
+								<aas:key type="Submodel" local="true" idType="IRI">"http://www.zvei.de/demo/submodel/12345679"</aas:key>
+								<aas:key type="Property" local="true" idType="IdShort">rotationSpeed</aas:key>
+							</aas:keys>
+						</aas:containedElementRef>
+					</aas:containedElements>
+				</aas:view>
+				<!-- This is a View with only the minimal required information in it. To test for Nullpointers and such. -->
+				<aas:view>
+					<aas:idShort>EmptyView</aas:idShort>
+					<aas:containedElements></aas:containedElements>
+				</aas:view>
+			</aas:views>
+			<aas:conceptDictionaries>
+				<aas:conceptDictionary>
+					<aas:idShort>SampleDic</aas:idShort>
+					<aas:conceptDescriptionRefs>
+						<aas:conceptDescriptionRef>
+							<aas:keys>
+								<aas:key type="ConceptDescription" local="true" idType="IRI">www.festo.com/dic/08111234</aas:key>
+							</aas:keys>
+						</aas:conceptDescriptionRef>
+					</aas:conceptDescriptionRefs>
+				</aas:conceptDictionary>
+			</aas:conceptDictionaries>
+		</aas:assetAdministrationShell>
+		<!-- This is an AAS with only the minimal required information in it. To test for Nullpointers and such. -->
+		<aas:assetAdministrationShell>
+			<aas:idShort>asset_admin_shell</aas:idShort>
+			<aas:identification idType="IRI">www.admin-shell.io/aas-sample/1/1</aas:identification>
+			<aas:assetRef>
+				<aas:keys>
+					<aas:key type="Asset" local="false" idType="IRI">http://pk.festo.com/3s7plfdrs35</aas:key>
+				</aas:keys>
+			</aas:assetRef>
+		</aas:assetAdministrationShell>
+	</aas:assetAdministrationShells>
+	<aas:assets>
+		<!-- This Asset is populated with all possible fields -->
+		<aas:asset>
+			<aas:idShort>3s7plfdrs35_asset1</aas:idShort>
+			<aas:category>asset1_categogy</aas:category>
+			<aas:description>
+				<aas:langString lang="EN">asset1_Description</aas:langString>
+			</aas:description>
+			<aas:parent>
+				<!-- Parent is currently a String in the Schema. But it should be a Reference. -->
+				<aas:keys>
+					<aas:key idType="IRI" local="false" type="Asset">asset_parent_id</aas:key>
+				</aas:keys>
+			</aas:parent>
+			<aas:identification idType="IRI">http://pk.festo.com/3s7plfdrs35</aas:identification>
+			<aas:administration>
+				<aas:version>1</aas:version>
+				<aas:revision>0</aas:revision>
+			</aas:administration>
+			<aas:embeddedDataSpecification>
+				<aas:dataSpecificationContent>
+					<aas:dataSpecificationIEC61360>
+						<IEC61360:preferredName>
+							<IEC61360:langString lang="DE">Drehzahl</IEC61360:langString>
+							<IEC61360:langString lang="EN">Rotation Speed</IEC61360:langString>
+						</IEC61360:preferredName>
+						<IEC61360:shortName>
+							<IEC61360:langString lang="DE">N</IEC61360:langString>
+						</IEC61360:shortName>
+						<IEC61360:unit>1/min</IEC61360:unit>
+						<IEC61360:unitId>
+							<IEC61360:keys>
+								<IEC61360:key local="false" type="GlobalReference" idType="IRDI">0173-1#05-AAA650#002</IEC61360:key>
+							</IEC61360:keys>
+						</IEC61360:unitId>
+						<IEC61360:valueFormat>NR1..5</IEC61360:valueFormat>
+					</aas:dataSpecificationIEC61360>
+				</aas:dataSpecificationContent>
+				<aas:dataSpecification>
+					<aas:keys>
+						<aas:key idType="IRI" local="false" type="GlobalReference">www.admin-shell.io/DataSpecificationTemplates/DataSpecificationIEC61360</aas:key>
+					</aas:keys>
+				</aas:dataSpecification>
+			</aas:embeddedDataSpecification>
+			<aas:assetIdentificationModelRef>
+				<aas:keys>
+					<aas:key type="ConceptDescription" local="true" idType="IRI">www.festo.com/dic/08111234</aas:key>
+				</aas:keys>
+			</aas:assetIdentificationModelRef>
+			<aas:kind>Instance</aas:kind>
+		</aas:asset>
+		<aas:asset>
+			<aas:idShort>emptyAsset</aas:idShort>
+			<aas:identification idType="IRI">http://pk.festo.com/q30j38dlajx</aas:identification>
+			<aas:kind>Instance</aas:kind>
+		</aas:asset>
+	</aas:assets>
+	<aas:submodels>
+		<!-- This Submodel is populated with all possible fields -->
+		<aas:submodel>
+			<aas:idShort>submodel1</aas:idShort>
+			<aas:category>submodel1_categogy</aas:category>
+			<aas:description>
+				<aas:langString lang="EN">submode1_decription</aas:langString>
+			</aas:description>
+			<aas:parent>
+				<!-- Parent is currently a String in the Schema. But it should be a Reference. -->
+				<aas:keys>
+					<aas:key idType="IRI" local="false" type="Submodel">submodel_parent_id</aas:key>
+				</aas:keys>
+			</aas:parent>
+			<aas:identification idType="IRI">http://www.zvei.de/demo/submodel/12345679</aas:identification>
+			<aas:administration>
+				<aas:version>1</aas:version>
+				<aas:revision>0</aas:revision>
+			</aas:administration>
+			<aas:kind>Instance</aas:kind>
+			<aas:semanticId>
+				<aas:keys>
+					<aas:key idType="IRI" local="false" type="Submodel">http://www.zvei.de/demo/submodelDefinitions/87654346</aas:key>
+				</aas:keys>
+			</aas:semanticId>
+			<aas:qualifier>
+				<aas:qualifiers>
+					<aas:formula>
+						<aas:dependsOnRefs>
+							<aas:reference>
+								<aas:keys>
+									<aas:key local="false" type="GlobalReference" idType="IRDI">qualifier_reference</aas:key>
+								</aas:keys>
+							</aas:reference>
+						</aas:dependsOnRefs>
+					</aas:formula>
+				</aas:qualifiers>
+				<aas:qualifiers>
+					<aas:qualifier>
+						<aas:valueId>
+							<aas:keys>
+								<aas:key idType="IRI" local="false" type="Submodel">http://www.zvei.de/demo/submodelDefinitions/87654346</aas:key>
+							</aas:keys>
+						</aas:valueId>
+						<aas:value>qualifierValue</aas:value>
+						<aas:type>qualifierType</aas:type>
+						<aas:valueType>anyType</aas:valueType>
+						<aas:semanticId>
+							<aas:keys>
+								<aas:key idType="IRI" local="false" type="GlobalReference">http://www.zvei.de/demo/submodelDefinitions/87654346</aas:key>
+							</aas:keys>
+						</aas:semanticId>
+					</aas:qualifier>
+				</aas:qualifiers>
+			</aas:qualifier>
+			<aas:embeddedDataSpecification>
+				<aas:dataSpecificationContent>
+					<aas:dataSpecificationIEC61360>
+						<IEC61360:preferredName>
+							<IEC61360:langString lang="DE">Drehzahl</IEC61360:langString>
+							<IEC61360:langString lang="EN">Rotation Speed</IEC61360:langString>
+						</IEC61360:preferredName>
+						<IEC61360:shortName>
+							<IEC61360:langString lang="DE">N</IEC61360:langString>
+						</IEC61360:shortName>
+						<IEC61360:unit>1/min</IEC61360:unit>
+						<IEC61360:unitId>
+							<IEC61360:keys>
+								<IEC61360:key local="false" type="GlobalReference" idType="IRDI">0173-1#05-AAA650#002</IEC61360:key>
+							</IEC61360:keys>
+						</IEC61360:unitId>
+						<IEC61360:valueFormat>NR1..5</IEC61360:valueFormat>
+					</aas:dataSpecificationIEC61360>
+				</aas:dataSpecificationContent>
+				<aas:dataSpecification>
+					<aas:keys>
+						<aas:key idType="IRI" local="false" type="GlobalReference">www.admin-shell.io/DataSpecificationTemplates/DataSpecificationIEC61360</aas:key>
+					</aas:keys>
+				</aas:dataSpecification>
+			</aas:embeddedDataSpecification>
+			<aas:submodelElements>
+				<aas:submodelElement>
+					<aas:property>
+						<aas:idShort>rotationSpeed</aas:idShort>
+						<aas:category>VARIABLE</aas:category>
+						<aas:semanticId>
+							<aas:keys>
+								<aas:key idType="IRI" type="ConceptDescription" local="true">www.festo.com/dic/08111234</aas:key>
+							</aas:keys>
+						</aas:semanticId>
+						<aas:qualifier>
+							<aas:qualifiers>
+								<aas:qualifier>
+									<aas:valueId>
+										<aas:keys>
+											<aas:key idType="IRI" local="false" type="Submodel">http://www.zvei.de/demo/submodelDefinitions/87654346</aas:key>
+										</aas:keys>
+									</aas:valueId>
+									<aas:value>qualifierValue</aas:value>
+									<aas:type>qualifierType</aas:type>
+									<aas:valueType>anyType</aas:valueType>
+									<aas:semanticId>
+										<aas:keys>
+											<aas:key idType="IRI" local="false" type="GlobalReference">http://www.zvei.de/demo/submodelDefinitions/87654346</aas:key>
+										</aas:keys>
+									</aas:semanticId>
+								</aas:qualifier>
+							</aas:qualifiers>
+						</aas:qualifier>
+						<aas:embeddedDataSpecification>
+							<aas:dataSpecificationContent>
+								<aas:dataSpecificationIEC61360>
+									<IEC61360:preferredName>
+										<IEC61360:langString lang="DE">Drehzahl</IEC61360:langString>
+										<IEC61360:langString lang="EN">Rotation Speed</IEC61360:langString>
+									</IEC61360:preferredName>
+									<IEC61360:shortName>
+										<IEC61360:langString lang="DE">N</IEC61360:langString>
+									</IEC61360:shortName>
+									<IEC61360:unit>1/min</IEC61360:unit>
+									<IEC61360:unitId>
+										<IEC61360:keys>
+											<IEC61360:key local="false" type="GlobalReference" idType="IRDI">0173-1#05-AAA650#002</IEC61360:key>
+										</IEC61360:keys>
+									</IEC61360:unitId>
+									<IEC61360:valueFormat>NR1..5</IEC61360:valueFormat>
+								</aas:dataSpecificationIEC61360>
+							</aas:dataSpecificationContent>
+							<aas:dataSpecification>
+								<aas:keys>
+									<aas:key idType="IRI" local="false" type="GlobalReference">www.admin-shell.io/DataSpecificationTemplates/DataSpecificationIEC61360</aas:key>
+								</aas:keys>
+							</aas:dataSpecification>
+						</aas:embeddedDataSpecification>
+						<aas:value>2000</aas:value>
+						<aas:valueType>double</aas:valueType>
+					</aas:property>
+				</aas:submodelElement>
+				<aas:submodelElement>
+					<aas:property>
+						<aas:idShort>emptyDouble</aas:idShort>
+						<aas:valueType>double</aas:valueType>
+					</aas:property>
+				</aas:submodelElement>
+				<aas:submodelElement>
+					<aas:basicEvent>
+						<aas:idShort>basic_event_id</aas:idShort>
+						<aas:observed>
+							<aas:keys>
+								<aas:key idType="IRI" local="false" type="Submodel">http://www.zvei.de/demo/submodelDefinitions/87654346</aas:key>
+							</aas:keys>
+						</aas:observed>
+					</aas:basicEvent>
+				</aas:submodelElement>
+				<aas:submodelElement>
+					<aas:entity>
+						<aas:idShort>entity_id</aas:idShort>
+						<aas:assetRef>
+							<aas:keys>
+								<aas:key idType="IRI" local="false" type="Submodel">http://www.zvei.de/demo/submodelDefinitions/87654346</aas:key>
+							</aas:keys>
+						</aas:assetRef>
+						<aas:entityType>CoManagedEntity</aas:entityType>
+						<aas:statements>
+							<!-- XML Schema currently supports only one statement, but multiple should be supported -->
+							<aas:submodelElement>
+								<aas:file>
+									<aas:idShort>file_ID</aas:idShort>
+									<aas:mimeType>file_mimetype</aas:mimeType>
+									<aas:value>file_value</aas:value>
+								</aas:file>
+							</aas:submodelElement>
+							<aas:submodelElement>
+								<aas:range>
+									<aas:idShort>range_id</aas:idShort>
+									<aas:min>10</aas:min>
+									<aas:valueType>int</aas:valueType>
+								</aas:range>
+							</aas:submodelElement>
+						</aas:statements>
+					</aas:entity>
+				</aas:submodelElement>
+				<aas:submodelElement>
+					<aas:multiLanguageProperty>
+						<aas:idShort>multi_language_property_id</aas:idShort>
+						<aas:valueId>
+							<aas:keys>
+								<aas:key local="false" type="GlobalReference" idType="IRDI">0173-1#05-AAA650#002</aas:key>
+							</aas:keys>
+						</aas:valueId>
+						<aas:value>
+							<aas:langString lang="DE">Eine Beschreibung auf deutsch</aas:langString>
+							<aas:langString lang="EN">A description in english</aas:langString>
+						</aas:value>
+					</aas:multiLanguageProperty>
+				</aas:submodelElement>
+				<aas:submodelElement>
+					<aas:range>
+						<aas:idShort>range_id</aas:idShort>
+						<aas:max>10</aas:max>
+						<aas:min>1</aas:min>
+						<aas:valueType>int</aas:valueType>
+					</aas:range>
+				</aas:submodelElement>
+				<aas:submodelElement>
+					<aas:file>
+						<aas:idShort>file_id</aas:idShort>
+						<aas:mimeType>file_mimetype</aas:mimeType>
+						<aas:value>file_value</aas:value>
+					</aas:file>
+				</aas:submodelElement>
+				<aas:submodelElement>
+					<aas:blob>
+						<aas:idShort>blob_id</aas:idShort>
+						<aas:value>YmxvYit2YWx1ZQ==</aas:value>
+						<aas:mimeType>blob_mimetype</aas:mimeType>
+					</aas:blob>
+				</aas:submodelElement>
+				<aas:submodelElement>
+					<aas:referenceElement>
+						<aas:idShort>reference_ELE_ID</aas:idShort>
+						<aas:value>
+							<aas:keys>
+								<aas:key local="false" type="GlobalReference" idType="IRDI">0173-1#05-AAA650#002</aas:key>
+							</aas:keys>
+						</aas:value>
+					</aas:referenceElement>
+				</aas:submodelElement>
+				<aas:submodelElement>
+					<aas:submodelElementCollection>
+						<aas:idShort>submodelElementCollection_ID</aas:idShort>
+						<aas:allowDuplicates>true</aas:allowDuplicates>
+						<aas:ordered>false</aas:ordered>
+						<aas:value>
+							<aas:submodelElement>
+								<aas:file>
+									<aas:idShort>file_ID</aas:idShort>
+									<aas:mimeType>file_mimetype</aas:mimeType>
+									<aas:value>file_value</aas:value>
+								</aas:file>
+							</aas:submodelElement>
+							<aas:submodelElement>
+								<aas:blob>
+									<aas:idShort>blob_id</aas:idShort>
+									<aas:value>YmxvYit2YWx1ZQ==</aas:value>
+									<aas:mimeType>blob_mimetype</aas:mimeType>
+								</aas:blob>
+							</aas:submodelElement>
+						</aas:value>
+					</aas:submodelElementCollection>
+				</aas:submodelElement>
+				<aas:submodelElement>
+					<aas:relationshipElement>
+						<aas:idShort>relationshipElement_ID</aas:idShort>
+						<aas:first>
+							<aas:keys>
+								<aas:key local="false" type="GlobalReference" idType="IRDI">0173-1#05-AAA650#001</aas:key>
+							</aas:keys>
+						</aas:first>
+						<aas:second>
+							<aas:keys>
+								<aas:key local="false" type="GlobalReference" idType="IRDI">0173-1#05-AAA650#002</aas:key>
+							</aas:keys>
+						</aas:second>
+					</aas:relationshipElement>
+				</aas:submodelElement>
+				<aas:submodelElement>
+					<aas:operation>
+						<aas:idShort>operation_ID</aas:idShort>
+						<aas:inoutputVariable>
+							<aas:operationVariable>
+								<aas:value>
+									<aas:referenceElement>
+										<aas:idShort>reference_ELE_ID2</aas:idShort>
+										<aas:value>
+											<aas:keys>
+												<aas:key local="false" type="GlobalReference" idType="IRDI">0173-1#05-AAA650#003</aas:key>
+											</aas:keys>
+										</aas:value>
+									</aas:referenceElement>
+								</aas:value>
+							</aas:operationVariable>
+						</aas:inoutputVariable>
+						<aas:inputVariable>
+							<!-- The schema only allows one opVar in inputVariable, one in outputVariable and one in inoutputVariable. The Metamodel allows 0..* in each -->
+							<!-- To be able to have multiple Vars they are surrounded by <aas:operationVariable>. This is also violating the Schema. -->
+							<aas:operationVariable>
+								<aas:value>
+									<aas:file>
+										<aas:idShort>file_ID</aas:idShort>
+										<aas:mimeType>file_mimetype</aas:mimeType>
+										<aas:value>file_value</aas:value>
+									</aas:file>
+								</aas:value>
+							</aas:operationVariable>
+							<aas:operationVariable>
+								<aas:value>
+									<aas:blob>
+										<aas:idShort>blob_ID</aas:idShort>
+										<aas:value>YmxvYit2YWx1ZQ==</aas:value>
+										<aas:mimeType>blob_mimetype</aas:mimeType>
+									</aas:blob>
+								</aas:value>
+							</aas:operationVariable>
+						</aas:inputVariable>
+						<aas:outputVariable>
+							<aas:operationVariable>
+								<aas:value>
+									<aas:referenceElement>
+										<aas:idShort>reference_ELE_ID</aas:idShort>
+										<aas:value>
+											<aas:keys>
+												<aas:key local="false" type="GlobalReference" idType="IRDI">0173-1#05-AAA650#002</aas:key>
+											</aas:keys>
+										</aas:value>
+									</aas:referenceElement>
+								</aas:value>
+							</aas:operationVariable>
+						</aas:outputVariable>
+					</aas:operation>
+				</aas:submodelElement>
+			</aas:submodelElements>
+		</aas:submodel>
+	</aas:submodels>
+	<aas:conceptDescriptions>
+		<!-- This ConceptDescription is populated with all possible fields -->
+		<aas:conceptDescription>
+			<aas:idShort>conceptDescription1</aas:idShort>
+			<aas:category>cs_category</aas:category>
+			<aas:description>
+				<aas:langString lang="EN">conceptDescription_Description</aas:langString>
+			</aas:description>
+			<aas:parent>
+				<!-- Parent is currently a String in the Schema. But it should be a Reference. -->
+				<aas:keys>
+					<aas:key idType="IRI" local="false" type="ConceptDescription">cs_parent_id</aas:key>
+				</aas:keys>
+			</aas:parent>
+			<aas:identification idType="IRI">www.festo.com/dic/08111234</aas:identification>
+			<aas:administration>
+				<aas:version>1</aas:version>
+				<aas:revision>0</aas:revision>
+			</aas:administration>
+			<aas:embeddedDataSpecification>
+				<aas:dataSpecificationContent>
+					<aas:dataSpecificationIEC61360>
+						<IEC61360:preferredName>
+							<IEC61360:langString lang="DE">Drehzahl</IEC61360:langString>
+							<IEC61360:langString lang="EN">Rotation Speed</IEC61360:langString>
+						</IEC61360:preferredName>
+						<IEC61360:shortName>
+							<IEC61360:langString lang="DE">N</IEC61360:langString>
+						</IEC61360:shortName>
+						<IEC61360:unit>1/min</IEC61360:unit>
+						<IEC61360:unitId>
+							<IEC61360:keys>
+								<IEC61360:key local="false" type="GlobalReference" idType="IRDI">0173-1#05-AAA650#002</IEC61360:key>
+							</IEC61360:keys>
+						</IEC61360:unitId>
+						<IEC61360:valueFormat>NR1..5</IEC61360:valueFormat>
+					</aas:dataSpecificationIEC61360>
+				</aas:dataSpecificationContent>
+				<aas:dataSpecification>
+					<aas:keys>
+						<aas:key idType="IRI" local="false" type="GlobalReference">www.admin-shell.io/DataSpecificationTemplates/DataSpecificationIEC61360</aas:key>
+					</aas:keys>
+				</aas:dataSpecification>
+			</aas:embeddedDataSpecification>
+			<aas:isCaseOf>
+				<aas:keys>
+					<aas:key idType="IRI" type="ConceptDescription" local="true">www.festo.com/dic/08111234</aas:key>
+					<aas:key idType="IRI" type="ConceptDescription" local="true">www.festo.com/dic/08111234_2</aas:key>
+				</aas:keys>
+			</aas:isCaseOf>
+		</aas:conceptDescription>
+	</aas:conceptDescriptions>
+</aas:aasenv>
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/basyx/components/AASServer/AASServerSuite.java b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/basyx/components/AASServer/AASServerSuite.java
deleted file mode 100644
index 10e3826..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/basyx/components/AASServer/AASServerSuite.java
+++ /dev/null
@@ -1,55 +0,0 @@
-package org.basyx.components.AASServer;
-
-import static org.junit.Assert.assertEquals;
-
-import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
-import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
-import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
-import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
-import org.eclipse.basyx.aas.registration.api.IAASRegistryService;
-import org.eclipse.basyx.aas.registration.memory.InMemoryRegistry;
-import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
-import org.eclipse.basyx.vab.protocol.api.IConnectorProvider;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * Suite for testing that the AAS Server component is set up correctly. The
- * tests here can be used by the component test itself and the integration test
- * 
- * @author schnicke
- *
- */
-public abstract class AASServerSuite {
-	protected IAASRegistryService aasRegistry;
-	private ConnectedAssetAdministrationShellManager manager;
-
-	private String aasId = "testId";
-
-	protected abstract String getURL();
-
-	@Before
-	public void setUp() {
-		// Create a dummy registry to test integration of XML AAS
-		aasRegistry = new InMemoryRegistry();
-
-		// Create ConnectedAASManager
-		IConnectorProvider connectorProvider = new HTTPConnectorProvider();
-		manager = new ConnectedAssetAdministrationShellManager(aasRegistry, connectorProvider);
-	}
-
-	@Test
-	public void testAddAAS() throws Exception {
-		AssetAdministrationShell shell = new AssetAdministrationShell();
-		IIdentifier identifier = new ModelUrn(aasId);
-		shell.setIdentification(identifier);
-		shell.setIdShort("aasIdShort");
-		
-		manager.createAAS(shell, identifier, getURL());
-
-		IAssetAdministrationShell remote = manager.retrieveAAS(identifier);
-		assertEquals(shell.getIdShort(), remote.getIdShort());
-	}
-
-}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/basyx/components/AASServer/ITAASServer.java b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/basyx/components/AASServer/ITAASServer.java
deleted file mode 100644
index 0b165a4..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/basyx/components/AASServer/ITAASServer.java
+++ /dev/null
@@ -1,43 +0,0 @@
-package org.basyx.components.AASServer;
-
-import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
-import org.eclipse.basyx.components.configuration.BaSyxDockerConfiguration;
-import org.junit.BeforeClass;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Tests the docker container using the test suite
- * 
- * @author schnicke
- *
- */
-public class ITAASServer extends AASServerSuite {
-
-	private static String URL;
-	
-	@Override
-	protected String getURL() {
-		return URL;
-	}
-
-	private static Logger logger = LoggerFactory.getLogger(AASServerSuite.class);
-
-	@BeforeClass
-	public static void setUpClass() {
-		logger.info("Running integration test...");
-
-		logger.info("Loading servlet configuration");
-		// Load the servlet configuration inside of the docker configuration from
-		// properties file
-		BaSyxContextConfiguration contextConfig = new BaSyxContextConfiguration();
-		contextConfig.loadFromResource(BaSyxContextConfiguration.DEFAULT_CONFIG_PATH);
-
-		// Load the docker environment configuration from properties file
-		logger.info("Loading docker configuration");
-		BaSyxDockerConfiguration dockerConfig = new BaSyxDockerConfiguration();
-		dockerConfig.loadFromResource(BaSyxDockerConfiguration.DEFAULT_CONFIG_PATH);
-
-		URL = "http://localhost:" + dockerConfig.getHostPort() + contextConfig.getContextPath();
-	}
-}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/basyx/components/AASServer/TestAASServer.java b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/basyx/components/AASServer/TestAASServer.java
deleted file mode 100644
index 758237e..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/basyx/components/AASServer/TestAASServer.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package org.basyx.components.AASServer;
-
-import java.io.IOException;
-
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
-import org.junit.BeforeClass;
-import org.xml.sax.SAXException;
-
-/**
- * Tests the component using the test suite
- * 
- * @author schnicke
- *
- */
-public class TestAASServer extends AASServerSuite {
-
-	private static AASServerComponent component;
-
-	@Override
-	protected String getURL() {
-		return component.getURL();
-	}
-
-	@BeforeClass
-	public static void setUpClass() throws ParserConfigurationException, SAXException, IOException {
-		BaSyxContextConfiguration config = new BaSyxContextConfiguration();
-		config.loadFromResource(BaSyxContextConfiguration.DEFAULT_CONFIG_PATH);
-
-		component = new AASServerComponent(config.getHostname(), config.getPort(), config.getContextPath(), config.getDocBasePath());
-		component.startComponent();
-	}
-}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/AASServerComponentTest.java b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/AASServerComponentTest.java
new file mode 100644
index 0000000..9f7bf2b
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/AASServerComponentTest.java
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.regression.AASServer;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import java.util.List;
+
+import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
+import org.eclipse.basyx.aas.registration.memory.InMemoryRegistry;
+import org.eclipse.basyx.components.aas.AASServerComponent;
+import org.eclipse.basyx.components.aas.configuration.AASServerBackend;
+import org.eclipse.basyx.components.aas.configuration.BaSyxAASServerConfiguration;
+import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * Tests if AASServerComponent correctly deregisteres automatically registered AASs/SMs
+ * 
+ * @author conradi
+ *
+ */
+public class AASServerComponentTest {
+
+	
+	private static AASServerComponent component;
+	private static InMemoryRegistry registry;
+	
+	@BeforeClass
+	public static void setUp() {
+		// Setup component's test configuration
+		BaSyxContextConfiguration contextConfig = new BaSyxContextConfiguration(8080, "");
+		BaSyxAASServerConfiguration aasConfig = new BaSyxAASServerConfiguration(AASServerBackend.INMEMORY, "xml/aas.xml");
+		
+		// Create and start AASServer component
+		component = new AASServerComponent(contextConfig, aasConfig);
+		registry = new InMemoryRegistry();
+		component.setRegistry(registry);
+		component.startComponent();
+	}
+	
+	/**
+	 * Tests if AASServerComponent deregisters all AASs/SMs that it registered automatically on startup
+	 */
+	@Test
+	public void testServerCleanup() {
+		
+		List<AASDescriptor> aasDescriptors = registry.lookupAll();
+		assertEquals(2, aasDescriptors.size());
+		
+		component.stopComponent();
+		
+		// Try to lookup all previously registered AASs
+		for(AASDescriptor aasDescriptor: aasDescriptors) {
+			try {
+				registry.lookupAAS(aasDescriptor.getIdentifier());
+				fail();
+			} catch (ResourceNotFoundException e) {
+			}
+			
+			// Try to lookup all previously registered SMs
+			for(SubmodelDescriptor smDescriptor: aasDescriptor.getSubmodelDescriptors()) {
+				try {
+					registry.lookupSubmodel(aasDescriptor.getIdentifier(), smDescriptor.getIdentifier());
+					fail();
+				} catch (ResourceNotFoundException e) {
+				}
+			}
+		}
+		
+	}
+}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/AASServerSuite.java b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/AASServerSuite.java
new file mode 100644
index 0000000..0ad88d7
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/AASServerSuite.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.regression.AASServer;
+
+import static org.junit.Assert.assertEquals;
+
+import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
+import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
+import org.eclipse.basyx.aas.registration.memory.InMemoryRegistry;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.vab.protocol.api.IConnectorFactory;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorFactory;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Suite for testing that the AAS Server component is set up correctly. The
+ * tests here can be used by the component test itself and the integration test
+ * 
+ * @author espen
+ *
+ */
+public abstract class AASServerSuite {
+	protected IAASRegistry aasRegistry;
+	protected ConnectedAssetAdministrationShellManager manager;
+
+	protected String aasId = "testId";
+
+	protected abstract String getURL();
+
+	@Before
+	public void setUp() {
+		// Create a dummy registry to test integration of XML AAS
+		aasRegistry = new InMemoryRegistry();
+
+		// Create ConnectedAASManager
+		IConnectorFactory connectorFactory = new HTTPConnectorFactory();
+		manager = new ConnectedAssetAdministrationShellManager(aasRegistry, connectorFactory);
+	}
+
+	@Test
+	public void testAddAAS() throws Exception {
+		AssetAdministrationShell shell = new AssetAdministrationShell();
+		IIdentifier identifier = new ModelUrn(aasId);
+		shell.setIdentification(identifier);
+		shell.setIdShort("aasIdShort");
+		manager.createAAS(shell, getURL());
+
+		IAssetAdministrationShell remote = manager.retrieveAAS(identifier);
+		assertEquals(shell.getIdShort(), remote.getIdShort());
+	}
+}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/AASXSuite.java b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/AASXSuite.java
new file mode 100644
index 0000000..2890927
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/AASXSuite.java
@@ -0,0 +1,185 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.regression.AASServer;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Map;
+
+import javax.ws.rs.client.Client;
+import javax.ws.rs.client.ClientBuilder;
+import javax.ws.rs.client.Invocation;
+import javax.ws.rs.client.WebTarget;
+import javax.ws.rs.core.Response;
+
+import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
+import org.eclipse.basyx.aas.metamodel.connected.ConnectedAssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
+import org.eclipse.basyx.aas.registration.memory.InMemoryRegistry;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElementCollection;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IFile;
+import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.ConnectedSubmodelElementCollection;
+import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.dataelement.ConnectedFile;
+import org.eclipse.basyx.vab.protocol.api.IConnectorFactory;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorFactory;
+import org.junit.Before;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Suite for testing that the XMLAAS servlet is set up correctly. The tests here
+ * can be used by the servlet test itself and the integration test
+ * 
+ * @author schnicke, espen
+ *
+ */
+public abstract class AASXSuite {
+	private static Logger logger = LoggerFactory.getLogger(AASXSuite.class);
+
+	protected IAASRegistry aasRegistry;
+
+	protected static final String aasShortId = "Festo_3S7PM0CP4BD";
+	protected static final ModelUrn aasId = new ModelUrn("smart.festo.com/demo/aas/1/1/454576463545648365874");
+	protected static final ModelUrn smId = new ModelUrn("www.company.com/ids/sm/4343_5072_7091_3242");
+	protected static final String smShortId = "Nameplate";
+
+	// Has to be individualized by each test inheriting from this suite
+	protected static String aasEndpoint;
+	protected static String smEndpoint;
+	protected static String rootEndpoint;
+
+	private ConnectedAssetAdministrationShellManager manager;
+
+	// create a REST client
+	private Client client = ClientBuilder.newClient();
+
+	/**
+	 * Before each test, a dummy registry is created and an AAS is added in the
+	 * registry
+	 */
+	@Before
+	public void setUp() {
+		// Create a dummy registry to test integration of XML AAS
+		aasRegistry = new InMemoryRegistry();
+		AASDescriptor descriptor = new AASDescriptor(aasShortId, aasId, aasEndpoint);
+		descriptor.addSubmodelDescriptor(new SubmodelDescriptor(smShortId, smId, smEndpoint));
+		aasRegistry.register(descriptor);
+
+		// Create a ConnectedAssetAdministrationShell using a
+		// ConnectedAssetAdministrationShellManager
+		IConnectorFactory connectorFactory = new HTTPConnectorFactory();
+		manager = new ConnectedAssetAdministrationShellManager(aasRegistry, connectorFactory);
+	}
+
+	@Test
+	public void testGetSingleAAS() throws Exception {
+		ConnectedAssetAdministrationShell connectedAssetAdministrationShell = getConnectedAssetAdministrationShell();
+		assertEquals(aasShortId, connectedAssetAdministrationShell.getIdShort());
+	}
+
+	@Test
+	public void testGetSingleSubmodel() throws Exception {
+		ISubmodel subModel = getConnectedSubmodel();
+		assertEquals(smShortId, subModel.getIdShort());
+	}
+
+	@Test
+	public void testGetSingleModule() throws Exception {
+		final String FILE_ENDING = "files/aasx/Nameplate/marking_rcm.jpg";
+		final String FILE_PATH = rootEndpoint + "files/aasx/Nameplate/marking_rcm.jpg";
+		checkFile(FILE_PATH);
+
+		// Get the submdoel nameplate
+		ISubmodel nameplate = getConnectedSubmodel();
+		// Get the submodel element collection marking_rcm
+		ConnectedSubmodelElementCollection marking_rcm = (ConnectedSubmodelElementCollection) nameplate.getSubmodelElements().get("Marking_RCM");
+		Collection<ISubmodelElement> values = marking_rcm.getValue();
+
+		// navigate to the File element
+		Iterator<ISubmodelElement> iter = values.iterator();
+		while (iter.hasNext()) {
+			ISubmodelElement element = iter.next();
+			if (element instanceof ConnectedFile) {
+				ConnectedFile connectedFile = (ConnectedFile) element;
+				// get value of the file element
+
+				String fileurl = connectedFile.getValue();
+				assertTrue(fileurl.endsWith(FILE_ENDING));
+			}
+		}
+	}
+
+	@Test
+	public void testAllFiles() throws Exception {
+		logger.info("Checking all files");
+		ConnectedAssetAdministrationShell aas = getConnectedAssetAdministrationShell();
+		logger.info("AAS idShort: " + aas.getIdShort());
+		logger.info("AAS identifier: " + aas.getIdentification().getId());
+		Map<String, ISubmodel> submodels = aas.getSubmodels();
+		logger.info("# Submodels: " + submodels.size());
+		for (ISubmodel sm : submodels.values()) {
+			logger.info("Checking submodel: " + sm.getIdShort());
+			checkElementCollectionFiles(sm.getSubmodelElements().values());
+		}
+
+	}
+
+	private void checkElementCollectionFiles(Collection<ISubmodelElement> elements) {
+		for (ISubmodelElement element : elements) {
+			if (element instanceof IFile) {
+				String fileUrl = ((IFile) element).getValue();
+				checkFile(fileUrl);
+			} else if (element instanceof ISubmodelElementCollection) {
+				ISubmodelElementCollection col = (ISubmodelElementCollection) element;
+				checkElementCollectionFiles(col.getSubmodelElements().values());
+			}
+		}
+	}
+
+	private void checkFile(String absolutePath) {
+		// connect to the url of the aas
+		WebTarget webTarget = client.target(absolutePath);
+		logger.info("Checking file: " + absolutePath);
+		Invocation.Builder invocationBuilder = webTarget.request();
+		Response response = invocationBuilder.get();
+
+		// validate the response
+		assertEquals("Path check failed: " + absolutePath, 200, response.getStatus());
+	}
+
+	/**
+	 * Gets the connected Asset Administration Shell
+	 * 
+	 * @return connected AAS
+	 * @throws Exception
+	 */
+	private ConnectedAssetAdministrationShell getConnectedAssetAdministrationShell() throws Exception {
+		return manager.retrieveAAS(aasId);
+	}
+
+	/**
+	 * Gets the connected Submodel
+	 * 
+	 * @return connected SM
+	 * @throws Exception
+	 */
+	private ISubmodel getConnectedSubmodel() {
+		return manager.retrieveSubmodel(aasId, smId);
+	}
+}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/SimpleNoOpAASSubmodel.java b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/SimpleNoOpAASSubmodel.java
new file mode 100644
index 0000000..b115f5c
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/SimpleNoOpAASSubmodel.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.regression.AASServer;
+
+import java.util.Map;
+
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation;
+import org.eclipse.basyx.testsuite.regression.submodel.restapi.SimpleAASSubmodel;
+
+public class SimpleNoOpAASSubmodel extends SimpleAASSubmodel {
+
+	public SimpleNoOpAASSubmodel() {
+		this("SimpleAASSubmodel");
+	}
+
+	public SimpleNoOpAASSubmodel(String idShort) {
+		super(idShort);
+
+		// Remove operations
+		deleteSubmodelElement("complex");
+		deleteSubmodelElement("simple");
+		deleteSubmodelElement("exception1");
+		deleteSubmodelElement("exception2");
+
+		Map<String, ISubmodelElement> elems = this.getSubmodelElements();
+		SubmodelElementCollection root = (SubmodelElementCollection) elems.get("containerRoot");
+		SubmodelElementCollection opContainer = (SubmodelElementCollection) root.getSubmodelElement("container");
+		opContainer.deleteSubmodelElement("operationId");
+		Operation opReplacement = new Operation("operationId");
+		opContainer.addSubmodelElement(opReplacement);
+	}
+
+}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/TestAASXAASServer.java b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/TestAASXAASServer.java
new file mode 100644
index 0000000..5286a05
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/TestAASXAASServer.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.regression.AASServer;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URISyntaxException;
+
+import javax.servlet.ServletException;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.eclipse.basyx.aas.aggregator.restapi.AASAggregatorProvider;
+import org.eclipse.basyx.components.aas.AASServerComponent;
+import org.eclipse.basyx.components.aas.configuration.AASServerBackend;
+import org.eclipse.basyx.components.aas.configuration.BaSyxAASServerConfiguration;
+import org.eclipse.basyx.components.aas.executable.AASServerExecutable;
+import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.xml.sax.SAXException;
+/**
+ * Test accessing to AAS using basys aas SDK
+ * 
+ * @author zhangzai
+ *
+ */
+public class TestAASXAASServer extends AASXSuite {
+	private static Logger logger = LoggerFactory.getLogger(TestAASXAASServer.class);
+	private static AASServerComponent component;
+
+	@BeforeClass
+	public static void setUpClass() throws ParserConfigurationException, SAXException, IOException, URISyntaxException, ServletException {
+		// Setup component's test configuration
+		BaSyxContextConfiguration contextConfig = new BaSyxContextConfiguration();
+		contextConfig.loadFromResource(BaSyxContextConfiguration.DEFAULT_CONFIG_PATH);
+		BaSyxAASServerConfiguration aasConfig = new BaSyxAASServerConfiguration(AASServerBackend.INMEMORY, "aasx/01_Festo.aasx");
+		
+		// Load the additional file path relative to the executed jar file
+		String rootPath = new File(AASServerExecutable.class.getProtectionDomain().getCodeSource().getLocation().toURI()).getParentFile().getPath();
+		String docBasePath = rootPath;
+		contextConfig.setDocBasePath(docBasePath);
+
+		// Start the component
+		component = new AASServerComponent(contextConfig, aasConfig);
+		component.startComponent();
+		
+		rootEndpoint = "http://" + contextConfig.getHostname() + ":" + contextConfig.getPort() + "/"
+				+ contextConfig.getContextPath() + "/";
+		aasEndpoint = rootEndpoint + "/" + AASAggregatorProvider.PREFIX + "/" + aasId.getEncodedURN() + "/aas";
+		smEndpoint = aasEndpoint + "/submodels/" + smShortId + "/submodel";
+		logger.info("AAS URL for servlet test: " + aasEndpoint);
+	}
+
+	@AfterClass
+	public static void tearDownClass() {
+		component.stopComponent();
+	}
+}
+
+
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/TestAASXPackageManager.java b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/TestAASXPackageManager.java
new file mode 100644
index 0000000..6f14e3f
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/TestAASXPackageManager.java
@@ -0,0 +1,389 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.regression.AASServer;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+
+import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
+import org.eclipse.basyx.aas.factory.aasx.AASXFactory;
+import org.eclipse.basyx.aas.factory.aasx.InMemoryFile;
+import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.api.parts.asset.AssetKind;
+import org.eclipse.basyx.aas.metamodel.api.parts.asset.IAsset;
+import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
+import org.eclipse.basyx.aas.metamodel.map.parts.Asset;
+import org.eclipse.basyx.components.aas.aasx.AASXPackageManager;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.api.parts.IConceptDescription;
+import org.eclipse.basyx.submodel.metamodel.api.reference.IKey;
+import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.File;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.support.bundle.AASBundle;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.xml.sax.SAXException;
+
+/**
+ * J-Unit tests for AASx package explorer. This test checks the parsing of aas,
+ * submodels, assets and concept-descriptions. it also checks whether the aas
+ * have correct references to the asets and submodels
+ * 
+ * @author zhangzai, conradi
+ *
+ */
+public class TestAASXPackageManager {
+	/**
+	 * path to the aasx package
+	 */
+	private static final String aasxPath = "aasx/01_Festo.aasx";
+	
+	private static final String CREATED_AASX_PATH = "test.aasx";
+
+	/**
+	 * the aasx package converter
+	 */
+	private static AASXPackageManager packageConverter;
+
+	/**
+	 * this string array is used to check the refs to submodels of aas
+	 */
+	private String[] submodelids = { "www.company.com/ids/sm/6053_5072_7091_5102", "smart.festo.com/demo/sm/instance/1/1/13B7CCD9BF7A3F24", "www.company.com/ids/sm/4343_5072_7091_3242", "www.company.com/ids/sm/2543_5072_7091_2660",
+			"www.company.com/ids/sm/6563_5072_7091_4267"
+			
+	};
+	
+	/**
+	 * Files that are unzipped
+	 */
+	private static String[] unzipFiles = { "target/files/aasx/Document/docu.pdf", "target/files/icon.png"
+	};
+
+	/**
+	 * AAS bundle which will be generated by the XMLAASBundleFactory
+	 */
+	private Set<AASBundle> aasBundles;
+
+	/**
+	 * Submodels parsed by the converter
+	 */
+	private Set<ISubmodel> submodels;
+
+	/**
+	 * Initialize the AASX package converter
+	 */
+	@BeforeClass
+	public static void setup() {
+		// Create the aasx package converter with the path to the aasx package
+		packageConverter = new AASXPackageManager(aasxPath);
+	}
+
+	/**
+	 * Test parsing of aas, assets, submodels and concept-descriptions
+	 */
+	@Test
+	public void testCheckAasxConverter() {
+		// Parse aas from the XML and create the AAS Bundle with refs to submodels
+		try {
+			aasBundles = packageConverter.retrieveAASBundles();
+		} catch (ParserConfigurationException | SAXException | IOException | InvalidFormatException e) {
+			e.printStackTrace();
+		}
+
+		// check the information in the aas bundles
+		checkAASs(aasBundles);
+
+		// Check the submodels
+		checkSubmodels(submodels);
+	}
+	
+	
+	/**
+	 * Creates a new .aasx using the AASXFactory and tries to parse it
+	 */
+	@Test
+	public void testLoadGeneratedAASX()
+			throws InvalidFormatException, IOException, ParserConfigurationException, SAXException, TransformerException, URISyntaxException {
+		
+		List<IAssetAdministrationShell> aasList = new ArrayList<>();
+		List<ISubmodel> submodelList = new ArrayList<>();
+		List<IAsset> assetList = new ArrayList<>();
+		List<IConceptDescription> conceptDescriptionList = new ArrayList<>();
+
+		List<InMemoryFile> fileList = new ArrayList<>();
+		
+		Asset asset = new Asset("asset-id", new ModelUrn("ASSET_IDENTIFICATION"), AssetKind.INSTANCE);
+		AssetAdministrationShell aas = new AssetAdministrationShell("aasIdShort", new ModelUrn("aasId"), asset);
+		aas.setAssetReference((Reference) asset.getReference());
+		
+		Submodel sm = new Submodel("smIdShort", new ModelUrn("smId"));
+		
+		// Create File SubmodelElements
+		File file1 = new File("/icon.png", "image/png");
+		file1.setIdShort("file1");
+		File file2 = new File("/aasx/Document/docu.pdf", "application/pdf");
+		file2.setIdShort("file2");
+		
+		SubmodelElementCollection collection = new SubmodelElementCollection("Marking_RCM");
+		collection.addSubmodelElement(file1);
+		
+		sm.addSubmodelElement(collection);
+		sm.addSubmodelElement(file2);
+		aas.addSubmodel(sm);
+		
+		aasList.add(aas);
+		submodelList.add(sm);
+		assetList.add(asset);
+
+		// Build InMemoryFiles for .aasx
+		byte[] content1 = {5,6,7,8,9};
+		InMemoryFile file = new InMemoryFile(content1, "/icon.png");
+		fileList.add(file);
+		
+		byte[] content2 = {10,11,12,13,14};
+		file = new InMemoryFile(content2, "aasx/Document/docu.pdf");
+		fileList.add(file);
+		
+		// Build AASX
+		FileOutputStream out = new FileOutputStream(CREATED_AASX_PATH);
+		AASXFactory.buildAASX(aasList, assetList, conceptDescriptionList, submodelList, fileList, out);
+		
+		AASXPackageManager packageManager = new AASXPackageManager(CREATED_AASX_PATH);
+		
+		checkBundle(packageManager.retrieveAASBundles(), aas, sm);
+		
+		// Unzip files from the .aasx
+		packageManager.unzipRelatedFiles();
+		
+		// Check if all expected files are present
+		for(String path: unzipFiles) {
+			assertTrue(new java.io.File(path).exists());
+		}
+		
+	}
+	
+	private void checkBundle(Set<AASBundle> bundles, IAssetAdministrationShell aas, ISubmodel sm) {
+		assertEquals(1, bundles.size());
+		AASBundle bundle = bundles.stream().findFirst().get();
+		
+		IAssetAdministrationShell parsedAAS = bundle.getAAS();
+		assertEquals(aas.getIdShort(), parsedAAS.getIdShort());
+		assertEquals(aas.getIdentification().getId(), parsedAAS.getIdentification().getId());
+		
+		assertEquals(1, bundle.getSubmodels().size());
+		ISubmodel parsedSubmodel = bundle.getSubmodels().stream().findFirst().get();
+		assertEquals(sm.getIdShort(), parsedSubmodel.getIdShort());
+		assertEquals(sm.getIdentification().getId(), parsedSubmodel.getIdentification().getId());
+		assertEquals(sm.getSubmodelElements().size(), parsedSubmodel.getSubmodelElements().size());
+	}
+	
+
+	/**
+	 * Check the parsed aas with expected ones
+	 * 
+	 * @param aasList
+	 */
+	private void checkAASs(Set<AASBundle> aasBundles) {
+		assertEquals(2, aasBundles.size());
+
+		IAssetAdministrationShell aas = null;
+
+		// select the AAS with a specific ID from the list
+		Optional<AASBundle> testAASBundleOptional = aasBundles.stream().filter(b -> b.getAAS().getIdShort().equals("Festo_3S7PM0CP4BD")).findFirst();
+		// verify there exist one aas with this ID
+		assertTrue(testAASBundleOptional.isPresent());
+
+		// Get the aasbundle from the filtered results
+		AASBundle testAASBundle = testAASBundleOptional.get();
+		aas = testAASBundle.getAAS();
+
+		// get submodels of this aas
+		submodels = testAASBundle.getSubmodels();
+
+		// verify short id
+		assertEquals("Festo_3S7PM0CP4BD", aas.getIdShort());
+		assertEquals("CONSTANT", aas.getCategory());
+
+		// verify id and id-type
+		assertEquals("smart.festo.com/demo/aas/1/1/454576463545648365874", aas.getIdentification().getId());
+		assertEquals(IdentifierType.IRI, aas.getIdentification().getIdType());
+
+
+		// Get submodel references
+		Collection<IReference> references = aas.getSubmodelReferences();
+
+		// this aas has 5 submodels
+		assertEquals(5, references.size());
+		List<IReference> referencelist = new ArrayList<>();
+		referencelist.addAll(references);
+
+		// sort the list for later assertion
+		// list is sorted by the last two characters of the id
+		referencelist.sort((x, y) -> {
+			String idx = x.getKeys().get(0).getValue();
+			String idy = y.getKeys().get(0).getValue();
+
+			String idx_end = idx.substring(idx.length() - 2);
+			int idxint = Integer.parseInt(idx_end);
+			String idy_end = idy.substring(idy.length() - 2);
+			int idyint = Integer.parseInt(idy_end);
+
+			return idxint - idyint;
+
+		});
+
+		// get First submodel reference
+		for (int i = 0; i < referencelist.size(); i++) {
+			IReference ref = referencelist.get(i);
+			List<IKey> refKeys = ref.getKeys();
+
+			// assert the submodel id
+			assertEquals(submodelids[i], refKeys.get(0).getValue());
+			// assert the id type
+			assertEquals("IRI", refKeys.get(0).getIdType().name());
+			// assert the model type
+			assertEquals("SUBMODEL", refKeys.get(0).getType().name());
+			// submodels are local
+			assertEquals(true, refKeys.get(0).isLocal());
+		}
+
+	}
+
+	/**
+	 * Check parsed submodels with expected ones
+	 * 
+	 * @param submodels
+	 */
+	private void checkSubmodels(Set<ISubmodel> submodels) {
+		assertEquals(5, submodels.size());
+
+		// filter the submodel with id "Nameplate"
+		Optional<ISubmodel> sm1Optional = submodels.stream().filter(s -> s.getIdShort().equals("Nameplate")).findFirst();
+		assertTrue(sm1Optional.isPresent());
+		ISubmodel sm1 = sm1Optional.get();
+
+		// verify short id, id-type, id and model-kind of the submodel
+		assertEquals("Nameplate", sm1.getIdShort());
+		assertEquals("IRI", sm1.getIdentification().getIdType().name());
+		assertEquals("www.company.com/ids/sm/4343_5072_7091_3242", sm1.getIdentification().getId());
+		assertEquals("Instance", sm1.getModelingKind().toString());
+
+		// ---------------------------------------------
+		// get 1st submodel element
+		// Get submodel elements
+		Map<String, ISubmodelElement> smElements = sm1.getSubmodelElements();
+
+		// get element manufacturing name
+		ISubmodelElement sele = smElements.get("ManufacturerName");
+
+		// verify short id
+		assertEquals("ManufacturerName", sele.getIdShort());
+
+		// verify category and model-kind, value and value-type
+		assertEquals("PARAMETER", sele.getCategory());
+		assertTrue(sele.getModelingKind().name().equalsIgnoreCase("Instance"));
+		Property prop = (Property) sele;
+		assertEquals("Festo AG & Co. KG", prop.getValue());
+		assertEquals(ValueType.String, prop.getValueType());
+
+		// get semantic id
+		IReference semantic = sele.getSemanticId();
+
+		IKey semanticKey = semantic.getKeys().get(0);
+		assertTrue(semanticKey.getType().name().equalsIgnoreCase("ConceptDescription"));
+		assertEquals("IRDI", semanticKey.getIdType().name());
+		assertEquals("0173-1#02-AAO677#002", semanticKey.getValue());
+		assertEquals(true, semanticKey.isLocal());
+
+		/// ---------------------------------------------
+		// get 2nd submodel element
+		// Get submodel elements
+		sele = smElements.get("ManufacturerProductDesignation");
+		assertEquals("ManufacturerProductDesignation", sele.getIdShort());
+		assertEquals("PARAMETER", sele.getCategory());
+		assertTrue(sele.getModelingKind().name().equalsIgnoreCase("Instance"));
+		prop = (Property) sele;
+		assertEquals("OVEL Vacuum generator", prop.getValue());
+		assertEquals(ValueType.String, prop.getValueType());
+
+		// get semantic id
+		semantic = sele.getSemanticId();
+		semanticKey = semantic.getKeys().get(0);
+		assertTrue(semanticKey.getType().name().equalsIgnoreCase("ConceptDescription"));
+		assertEquals("IRDI", semanticKey.getIdType().name());
+		assertEquals("0173-1#02-AAW338#001", semanticKey.getValue());
+		assertEquals(true, semanticKey.isLocal());
+
+		// ---------------------------------------------
+		// get 3rd submodel element
+		// Get submodel elements
+		sele = smElements.get("PhysicalAddress");
+		assertEquals("PhysicalAddress", sele.getIdShort());
+		assertEquals("PARAMETER", sele.getCategory());
+		assertTrue(sele.getModelingKind().name().equalsIgnoreCase("Instance"));
+
+		// get semantic id
+		semantic = sele.getSemanticId();
+		semanticKey = semantic.getKeys().get(0);
+		assertTrue(semanticKey.getType().name().equalsIgnoreCase("ConceptDescription"));
+		assertEquals("IRI", semanticKey.getIdType().name());
+		assertEquals("https://www.hsu-hh.de/aut/aas/physicaladdress", semanticKey.getValue());
+		assertEquals(true, semanticKey.isLocal());
+
+		// get values
+		assertTrue(sele.getModelType().equalsIgnoreCase("SubmodelElementCollection"));
+		SubmodelElementCollection collection = (SubmodelElementCollection) sele;
+		Map<String, ISubmodelElement> smElemMap = collection.getSubmodelElements();
+
+		assertEquals(5, smElemMap.size());
+		Property prop1 = (Property) smElemMap.get("CountryCode");
+		assertEquals("CountryCode", prop1.getIdShort());
+		assertEquals("DE", prop1.getValue());
+
+		Property prop2 = (Property) smElemMap.get("Street");
+		assertEquals("Street", prop2.getIdShort());
+		assertEquals("Ruiter Straße 82", prop2.getValue());
+	}
+	
+	
+	/**
+	 * Delete created files
+	 */
+	@AfterClass
+	public static void cleanUp() {
+		for(String path: unzipFiles) {
+			new java.io.File(path).delete();
+		}
+		new java.io.File(CREATED_AASX_PATH).delete();
+	}
+
+}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/TestFileEndpointLoader.java b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/TestFileEndpointLoader.java
new file mode 100644
index 0000000..4a49cdf
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/TestFileEndpointLoader.java
@@ -0,0 +1,96 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.regression.AASServer;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Map;
+
+import org.eclipse.basyx.components.aas.aasx.SubmodelFileEndpointLoader;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IFile;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.File;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests the SubmodelFileEndpointLoader 
+ * 
+ * @author espen
+ *
+ */
+public class TestFileEndpointLoader {
+	private Submodel submodel;
+	private final String relativePath = "/file/root/text.txt";
+	private final String absolutePath = "http://localhost:1234/file/root/text.txt";
+	private final String relativeTargetPath = "http://localhost:4321/new/file/root/text.txt";
+	
+	@Before
+	public void setup() {
+		File fRel = new File(relativePath, "application/json");
+		fRel.setIdShort("fRel");
+		File fAbs = new File(absolutePath, "application/json");
+		fAbs.setIdShort("fAbs");
+		SubmodelElementCollection col = new SubmodelElementCollection();
+		col.setIdShort("fileCollection");
+		File fCol = new File(relativePath, "application/json");
+		fCol.setIdShort("fInside");
+		col.addSubmodelElement(fCol);
+		submodel = new Submodel("FileTestSubmodel", new Identifier(IdentifierType.IRDI, "FileTestSubmodel"));
+		submodel.addSubmodelElement(fRel);
+		submodel.addSubmodelElement(fAbs);
+		submodel.addSubmodelElement(col);
+	}
+	
+	/**
+	 * Tests setting a static string endpoint (relative to the given path in the existing value)
+	 */
+	@Test
+	public void testRelativePaths1() {
+		SubmodelFileEndpointLoader.setRelativeFileEndpoints(submodel, "http://localhost:4321/new");
+		checkRelativeTargetPaths();
+	}
+
+	/**
+	 * Tests setting a endpoint via host, port and root path (relative to the given path in the existing value)
+	 */
+	@Test
+	public void testRelativePaths2() {
+		SubmodelFileEndpointLoader.setRelativeFileEndpoints(submodel, "localhost", 4321, "/new");
+		checkRelativeTargetPaths();
+	}
+
+	/**
+	 * Tests elements inside of collections
+	 */
+	@Test
+	public void testCollections() {
+		SubmodelFileEndpointLoader.setRelativeFileEndpoints(submodel, "localhost", 4321, "/new");
+
+		Map<String, ISubmodelElement> elements = submodel.getSubmodelElements();
+		SubmodelElementCollection col = (SubmodelElementCollection) elements.get("fileCollection");
+		IFile file = (IFile) col.getSubmodelElements().get("fInside");
+		assertEquals(relativeTargetPath, file.getValue());
+	}
+
+	private void checkRelativeTargetPaths() {
+		Map<String, ISubmodelElement> elements = submodel.getSubmodelElements();
+
+		String fromRelative = ((IFile) elements.get("fRel")).getValue();
+		assertEquals(relativeTargetPath, fromRelative);
+
+		String fromAbsolute = ((IFile) elements.get("fAbs")).getValue();
+		assertEquals(relativeTargetPath, fromAbsolute);
+	}
+}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/TestInMemoryAASServer.java b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/TestInMemoryAASServer.java
new file mode 100644
index 0000000..06531f3
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/TestInMemoryAASServer.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.regression.AASServer;
+
+import java.io.IOException;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.eclipse.basyx.components.aas.AASServerComponent;
+import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.xml.sax.SAXException;
+
+/**
+ * Tests the component using the test suite
+ * 
+ * @author schnicke
+ *
+ */
+public class TestInMemoryAASServer extends AASServerSuite {
+
+	private static AASServerComponent component;
+
+	@Override
+	protected String getURL() {
+		return component.getURL() + "/shells";
+	}
+
+	@BeforeClass
+	public static void setUpClass() throws ParserConfigurationException, SAXException, IOException {
+		BaSyxContextConfiguration config = new BaSyxContextConfiguration();
+		config.loadFromResource(BaSyxContextConfiguration.DEFAULT_CONFIG_PATH);
+
+		component = new AASServerComponent(config);
+		component.startComponent();
+	}
+
+	@AfterClass
+	public static void tearDownClass() {
+		component.stopComponent();
+	}
+}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/TestJSONAASServer.java b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/TestJSONAASServer.java
new file mode 100644
index 0000000..b74b9b3
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/TestJSONAASServer.java
@@ -0,0 +1,144 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.regression.AASServer;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Map;
+
+import org.eclipse.basyx.aas.aggregator.restapi.AASAggregatorProvider;
+import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
+import org.eclipse.basyx.aas.metamodel.connected.ConnectedAssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
+import org.eclipse.basyx.aas.registration.memory.InMemoryRegistry;
+import org.eclipse.basyx.components.aas.AASServerComponent;
+import org.eclipse.basyx.components.aas.configuration.AASServerBackend;
+import org.eclipse.basyx.components.aas.configuration.BaSyxAASServerConfiguration;
+import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.vab.protocol.api.IConnectorFactory;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorFactory;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Suite for testing that the JSONAAS servlet is set up correctly. The tests here
+ * can be used by the servlet test itself and the integration test
+ * 
+ * @author JSON
+ *
+ */
+public class TestJSONAASServer {
+	private static Logger logger = LoggerFactory.getLogger(TestJSONAASServer.class);
+
+	protected static final String aasShortId = "ExampleMotor";
+	protected static final ModelUrn aasId = new ModelUrn("http://customer.com/aas/9175_7013_7091_9168");
+	protected static final ModelUrn smId = new ModelUrn("http.//i40.customer.com/type/1/1/7A7104BDAB57E184");
+	protected static final String smShortId = "TechnicalData";
+	protected static final String smShortId2 = "Documentation";
+	protected static final String smShortId3 = "OperationalData";
+
+	// Has to be individualized by each test inheriting from this suite
+	protected static String aasEndpoint;
+	protected static String smEndpoint;
+
+	// Registry and AAS component
+	protected static IAASRegistry registry;
+	protected static AASServerComponent component;
+	protected static ConnectedAssetAdministrationShellManager manager;
+
+	@BeforeClass
+	public static void setUp() {
+		// Setup component's test configuration
+		BaSyxContextConfiguration contextConfig = new BaSyxContextConfiguration();
+		contextConfig.loadFromResource(BaSyxContextConfiguration.DEFAULT_CONFIG_PATH);
+		BaSyxAASServerConfiguration aasConfig = new BaSyxAASServerConfiguration(AASServerBackend.INMEMORY,
+				"json/aas.json");
+
+		// Setup endpoints
+		String rootEndpoint = "http://" + contextConfig.getHostname() + ":" + contextConfig.getPort() + "/"
+				+ contextConfig.getContextPath() + "/";
+		aasEndpoint = rootEndpoint + "/" + AASAggregatorProvider.PREFIX + "/" + aasId.getEncodedURN() + "/aas";
+		smEndpoint = aasEndpoint + "/submodels/" + smShortId + "/submodel";
+		logger.info("AAS URL for servlet test: " + aasEndpoint);
+
+		// Create and start AASServer component
+		component = new AASServerComponent(contextConfig, aasConfig);
+		registry = new InMemoryRegistry();
+		component.setRegistry(registry);
+		component.startComponent();
+
+		// Create a ConnectedAssetAdministrationShell using a
+		// ConnectedAssetAdministrationShellManager
+		IConnectorFactory connectorFactory = new HTTPConnectorFactory();
+		manager = new ConnectedAssetAdministrationShellManager(registry, connectorFactory);
+	}
+
+
+	@AfterClass
+	public static void tearDown() {
+		component.stopComponent();
+	}
+
+	@Test
+	public void testGetSingleAAS() throws Exception {
+		ConnectedAssetAdministrationShell connectedAssetAdministrationShell = getConnectedAssetAdministrationShell();
+		assertEquals(aasShortId, connectedAssetAdministrationShell.getIdShort());
+	}
+
+	@Test
+	public void testGetSingleSubmodel() throws Exception {
+		ISubmodel subModel = getConnectedSubmodel();
+		assertEquals(smShortId, subModel.getIdShort());
+	}
+
+	@Test
+	public void testGetAllSubmodels() throws Exception {
+		Map<String, ISubmodel> subModels = getAllConnectedSubmodels();
+		assertEquals(3, subModels.size());
+		assertEquals(smShortId, subModels.get(smShortId).getIdShort());
+		assertEquals(smShortId2, subModels.get(smShortId2).getIdShort());
+		assertEquals(smShortId3, subModels.get(smShortId3).getIdShort());
+	}
+
+	/**
+	 * Gets the connected Asset Administration Shell
+	 * 
+	 * @return connected AAS
+	 * @throws Exception
+	 */
+	private ConnectedAssetAdministrationShell getConnectedAssetAdministrationShell() throws Exception {
+		return manager.retrieveAAS(aasId);
+	}
+
+	/**
+	 * Gets the connected Submodel
+	 * 
+	 * @return connected SM
+	 * @throws Exception
+	 */
+	private ISubmodel getConnectedSubmodel() {
+		return manager.retrieveSubmodel(aasId, smId);
+	}
+
+	/**
+	 * Gets all connected Submodels
+	 * 
+	 * @return connected SM
+	 * @throws Exception
+	 */
+	private Map<String, ISubmodel> getAllConnectedSubmodels() {
+		return manager.retrieveSubmodels(aasId);
+	}
+}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/TestMongoDBAggregator.java b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/TestMongoDBAggregator.java
new file mode 100644
index 0000000..0295aa6
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/TestMongoDBAggregator.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.regression.AASServer;
+
+import org.eclipse.basyx.aas.aggregator.api.IAASAggregator;
+import org.eclipse.basyx.components.aas.mongodb.MongoDBAASAggregator;
+import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
+import org.eclipse.basyx.testsuite.regression.aas.aggregator.AASAggregatorSuite;
+
+public class TestMongoDBAggregator extends AASAggregatorSuite {
+
+	@Override
+	protected IAASAggregator getAggregator() {
+		MongoDBAASAggregator aggregator = new MongoDBAASAggregator(BaSyxContextConfiguration.DEFAULT_CONFIG_PATH);
+		aggregator.reset();
+
+		return aggregator;
+	}
+}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/TestMongoDBServer.java b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/TestMongoDBServer.java
new file mode 100644
index 0000000..c014157
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/TestMongoDBServer.java
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.regression.AASServer;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.IOException;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
+import org.eclipse.basyx.components.aas.AASServerComponent;
+import org.eclipse.basyx.components.aas.configuration.AASServerBackend;
+import org.eclipse.basyx.components.aas.configuration.BaSyxAASServerConfiguration;
+import org.eclipse.basyx.components.aas.mongodb.MongoDBAASAggregator;
+import org.eclipse.basyx.components.aas.mongodb.MongoDBSubmodelAPI;
+import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
+import org.eclipse.basyx.components.configuration.BaSyxMongoDBConfiguration;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.xml.sax.SAXException;
+
+/**
+ * Tests the component using the test suite
+ * 
+ * @author espen
+ *
+ */
+public class TestMongoDBServer extends AASServerSuite {
+
+	private static AASServerComponent component;
+	private static BaSyxMongoDBConfiguration mongoDBConfig;
+
+	@Override
+	protected String getURL() {
+		return component.getURL() + "/shells";
+	}
+
+	@BeforeClass
+	public static void setUpClass() throws ParserConfigurationException, SAXException, IOException {
+		// just reset the data with this default db configuration
+		new MongoDBAASAggregator(BaSyxContextConfiguration.DEFAULT_CONFIG_PATH).reset();
+
+		// Setup component configuration
+		BaSyxContextConfiguration contextConfig = new BaSyxContextConfiguration();
+		contextConfig.loadFromResource(BaSyxContextConfiguration.DEFAULT_CONFIG_PATH);
+		mongoDBConfig = new BaSyxMongoDBConfiguration();
+		BaSyxAASServerConfiguration aasConfig = new BaSyxAASServerConfiguration(AASServerBackend.MONGODB, "");
+
+		// Start component
+		component = new AASServerComponent(contextConfig, aasConfig, mongoDBConfig);
+		component.startComponent();
+	}
+
+	@Test
+	public void testAddSubmodelPersistency() throws Exception {
+		testAddAAS();
+
+		Submodel sm = new Submodel("MongoDB", new Identifier(IdentifierType.CUSTOM, "MongoDBId"));
+		manager.createSubmodel(new ModelUrn(aasId), sm);
+
+		MongoDBSubmodelAPI api = new MongoDBSubmodelAPI(mongoDBConfig, sm.getIdentification().getId());
+		ISubmodel persistentSM = api.getSubmodel();
+		assertEquals("MongoDB", persistentSM.getIdShort());
+	}
+
+	@AfterClass
+	public static void tearDownClass() {
+		component.stopComponent();
+	}
+}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/TestMongoDBSubmodelProvider.java b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/TestMongoDBSubmodelProvider.java
new file mode 100644
index 0000000..6004fd0
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/TestMongoDBSubmodelProvider.java
@@ -0,0 +1,123 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.regression.AASServer;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Collection;
+import java.util.Map;
+
+import org.eclipse.basyx.components.aas.mongodb.MongoDBAASAggregator;
+import org.eclipse.basyx.components.aas.mongodb.MongoDBSubmodelAPI;
+import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
+import org.eclipse.basyx.submodel.restapi.SubmodelProvider;
+import org.eclipse.basyx.testsuite.regression.submodel.restapi.SubmodelProviderTest;
+import org.eclipse.basyx.testsuite.regression.vab.protocol.http.TestsuiteDirectory;
+import org.eclipse.basyx.vab.manager.VABConnectionManager;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
+import org.eclipse.basyx.vab.protocol.api.ConnectorFactory;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class TestMongoDBSubmodelProvider extends SubmodelProviderTest {
+	private VABConnectionManager connManager;
+
+	@BeforeClass
+	public static void setUpClass() {
+		// just reset the data with this default db configuration
+		new MongoDBAASAggregator(BaSyxContextConfiguration.DEFAULT_CONFIG_PATH).reset();
+	}
+
+	@Override
+	protected VABConnectionManager getConnectionManager() {
+		if (connManager == null) {
+			connManager = new VABConnectionManager(new TestsuiteDirectory(), new ConnectorFactory() {
+				@Override
+				protected IModelProvider createProvider(String addr) {
+					SimpleNoOpAASSubmodel submodel = new SimpleNoOpAASSubmodel();
+					MongoDBSubmodelAPI api = new MongoDBSubmodelAPI("mySubmodelId");
+					api.setSubmodel(submodel);
+					IModelProvider smProvider = new SubmodelProvider(api);
+					// Simple submodel for testing specific mappings for submodels
+					return smProvider;
+				}
+			});
+		}
+		return connManager;
+	}
+
+	/**
+	 * Operations are not supported
+	 */
+	@Override
+	@Test
+	public void testDeleteOperation() {
+	}
+
+	/**
+	 * Operations are not supported
+	 */
+	@Override
+	@Test
+	public void testInvokeOperation() {
+	}
+	
+	/**
+	 * Operations are not supported
+	 */
+	@Override
+	@Test
+	public void testInvokeOperationInCollection() {
+	}
+
+	/**
+	 * Operations are not supported
+	 */
+	@Override
+	@Test
+	public void testInvokeAsync() throws Exception {
+	}
+
+	/**
+	 * Operations are not supported
+	 */
+	@Override
+	@Test
+	public void testInvokeAsyncException() throws Exception {
+	}
+
+	/**
+	 * Now 4 instead of 8 elements
+	 */
+	@SuppressWarnings("unchecked")
+	@Test
+	public void testReadSubmodelElements() {
+		VABElementProxy submodel = getConnectionManager().connectToVABElement(submodelAddr);
+		Collection<Map<String, Object>> set = (Collection<Map<String, Object>>) submodel
+				.getValue("/submodel/submodelElements");
+		assertEquals(4, set.size());
+	}
+
+	/**
+	 * Operations are not supported
+	 */
+	@Test
+	public void testReadSingleOperation() {
+	}
+
+	/**
+	 * testReadOperations
+	 */
+	@Test
+	public void testReadOperations() {
+	}
+
+}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/TestXMLAASServer.java b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/TestXMLAASServer.java
new file mode 100644
index 0000000..a5d00bf
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/TestXMLAASServer.java
@@ -0,0 +1,121 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.regression.AASServer;
+
+import static org.junit.Assert.assertEquals;
+
+import org.eclipse.basyx.aas.aggregator.restapi.AASAggregatorProvider;
+import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
+import org.eclipse.basyx.aas.metamodel.connected.ConnectedAssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
+import org.eclipse.basyx.aas.registration.memory.InMemoryRegistry;
+import org.eclipse.basyx.components.aas.AASServerComponent;
+import org.eclipse.basyx.components.aas.configuration.AASServerBackend;
+import org.eclipse.basyx.components.aas.configuration.BaSyxAASServerConfiguration;
+import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.vab.protocol.api.IConnectorFactory;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorFactory;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Suite for testing that the XMLAAS servlet is set up correctly. The tests here
+ * can be used by the servlet test itself and the integration test
+ * 
+ * @author schnicke
+ *
+ */
+public class TestXMLAASServer {
+	private static Logger logger = LoggerFactory.getLogger(TestXMLAASServer.class);
+
+	protected static final String aasShortId = "aas1";
+	protected static final ModelUrn aasId = new ModelUrn("www.admin-shell.io/aas-sample/2/0");
+	protected static final ModelUrn smId = new ModelUrn("http://www.zvei.de/demo/submodel/12345679");
+	protected static final String smShortId = "submodel1";
+
+	// Has to be individualized by each test inheriting from this suite
+	protected static String aasEndpoint;
+	protected static String smEndpoint;
+
+	// Registry and AAS component
+	protected static IAASRegistry registry;
+	protected static AASServerComponent component;
+	protected static ConnectedAssetAdministrationShellManager manager;
+
+	@BeforeClass
+	public static void setUp() {
+		// Setup component's test configuration
+		BaSyxContextConfiguration contextConfig = new BaSyxContextConfiguration();
+		contextConfig.loadFromResource(BaSyxContextConfiguration.DEFAULT_CONFIG_PATH);
+		BaSyxAASServerConfiguration aasConfig = new BaSyxAASServerConfiguration(AASServerBackend.INMEMORY, "xml/aas.xml");
+
+		// Setup endpoints
+		String rootEndpoint = "http://" + contextConfig.getHostname() + ":" + contextConfig.getPort() + "/"
+				+ contextConfig.getContextPath() + "/";
+		aasEndpoint = rootEndpoint + "/" + AASAggregatorProvider.PREFIX + "/" + aasId.getEncodedURN() + "/aas";
+		smEndpoint = aasEndpoint + "/submodels/" + smShortId + "/submodel";
+		logger.info("AAS URL for servlet test: " + aasEndpoint);
+
+		// Create and start AASServer component
+		component = new AASServerComponent(contextConfig, aasConfig);
+		registry = new InMemoryRegistry();
+		component.setRegistry(registry);
+		component.startComponent();
+
+		// Create a ConnectedAssetAdministrationShell using a
+		// ConnectedAssetAdministrationShellManager
+		IConnectorFactory connectorFactory = new HTTPConnectorFactory();
+		manager = new ConnectedAssetAdministrationShellManager(registry, connectorFactory);
+	}
+
+
+	@AfterClass
+	public static void tearDown() {
+		component.stopComponent();
+	}
+
+	@Test
+	public void testGetSingleAAS() throws Exception {
+		ConnectedAssetAdministrationShell connectedAssetAdministrationShell = getConnectedAssetAdministrationShell();
+		assertEquals(aasShortId, connectedAssetAdministrationShell.getIdShort());
+	}
+
+	@Test
+	public void testGetSingleSubmodel() throws Exception {
+		ISubmodel subModel = getConnectedSubmodel();
+		assertEquals(smShortId, subModel.getIdShort());
+	}
+
+	/**
+	 * Gets the connected Asset Administration Shell
+	 * 
+	 * @return connected AAS
+	 * @throws Exception
+	 */
+	private ConnectedAssetAdministrationShell getConnectedAssetAdministrationShell() throws Exception {
+		return manager.retrieveAAS(aasId);
+	}
+
+	/**
+	 * Gets the connected Submodel
+	 * 
+	 * @return connected SM
+	 * @throws Exception
+	 */
+	private ISubmodel getConnectedSubmodel() {
+		return manager.retrieveSubmodel(aasId, smId);
+	}
+
+}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/resources/.env b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/resources/.env
new file mode 100644
index 0000000..dc2072c
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/resources/.env
@@ -0,0 +1,38 @@
+# ##################
+# Docker Environment
+# ##################
+
+# ##################
+# Host Port
+# ##################
+# Specifies the port for the Docker HOST the container port is mapped to
+
+BASYX_HOST_PORT=8082
+
+# ##################
+# Container Port
+# ##################
+# Specifies the port for the Docker CONTAINER that is be mapped for the host 
+
+BASYX_CONTAINER_PORT=4001
+
+# ##################
+# Image Name
+# ##################
+# The image of the image that is build for this component
+
+BASYX_IMAGE_NAME=eclipsebasyx/aas-server
+
+# ##################
+# Image Tag
+# ##################
+# The image tag of the image that is build for this component
+
+BASYX_IMAGE_TAG=1.0.0
+
+# ##################
+# Container Name
+# ##################
+# The name of the container used for the default environment
+ 
+BASYX_CONTAINER_NAME=aas
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/resources/dockerMongodb.properties b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/resources/dockerMongodb.properties
new file mode 100644
index 0000000..7e9af7f
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/resources/dockerMongodb.properties
@@ -0,0 +1,34 @@
+# #############################
+# MongoDB Backend configuration
+# #############################
+
+# #############################
+# Database Name
+# #############################
+# The database in the MongoDB that hold the data
+
+dbname=admin
+
+# #############################
+# Connection String
+# #############################
+# MongoDB connection string for connecting to the MongoDB endpoint
+# Here it is not localhost, because the container has to address the mongodb
+# container in the default docker environment used in this component
+
+dbconnectionstring=mongodb://mongodb:27017/
+
+# #############################
+# AAS collections
+# #############################
+# Collection names that are used for storing the AAS and Submodels
+
+dbcollectionAAS=assetadministrationshells
+dbcollectionSubmodels=submodels
+
+# #############################
+# Registry Collections
+# #############################
+# Collection name that is used for storing registry data
+
+dbcollectionRegistry=registry
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/start.bat b/components/basys.components/basyx.components.docker/basyx.components.AASServer/start.bat
new file mode 100644
index 0000000..f0ff9e1
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/start.bat
@@ -0,0 +1,3 @@
+cd src/test/resources
+docker-compose up
+cd ../../..
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/start.sh b/components/basys.components/basyx.components.docker/basyx.components.AASServer/start.sh
new file mode 100755
index 0000000..4b9b54a
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/start.sh
@@ -0,0 +1,4 @@
+#!/usr/bin/env sh
+cd src/test/resources
+docker-compose up
+cd ../../..
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/stop.bat b/components/basys.components/basyx.components.docker/basyx.components.AASServer/stop.bat
new file mode 100644
index 0000000..b645246
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/stop.bat
@@ -0,0 +1,3 @@
+cd src/test/resources
+docker-compose down
+cd ../../..
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASServer/stop.sh b/components/basys.components/basyx.components.docker/basyx.components.AASServer/stop.sh
new file mode 100755
index 0000000..e11a931
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/stop.sh
@@ -0,0 +1,4 @@
+#!/usr/bin/env sh
+cd src/test/resources
+docker-compose down
+cd ../../..
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASX/Dockerfile b/components/basys.components/basyx.components.docker/basyx.components.AASX/Dockerfile
deleted file mode 100644
index 3628774..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.AASX/Dockerfile
+++ /dev/null
@@ -1,15 +0,0 @@
-# Add java runtime environment for execution
-FROM java:8-jdk-alpine 
-
-# Copy built jar to image using the jar name specified in the pom.xml (JAR_FILE)
-ARG JAR_FILE
-COPY target/${JAR_FILE} /usr/share/basyxExecutable.jar
-COPY target/lib /usr/share/lib
-COPY src/main/resources/context.properties /usr/share/context.properties
- 
-# Expose the appropriate port. In case of Tomcat, this is 8080.
-ARG PORT
-EXPOSE ${PORT}
- 
-# Start the jar
-CMD java -jar "/usr/share/basyxExecutable.jar" "/usr/share/context.properties"
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASX/docker-compose.yml b/components/basys.components/basyx.components.docker/basyx.components.AASX/docker-compose.yml
deleted file mode 100644
index 7e029c5..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.AASX/docker-compose.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-version: '3'
-services:
-
-  registry:
-    image: ${BASYX_IMAGE_NAME}:${BASYX_IMAGE_TAG}
-    container_name: ${BASYX_CONTAINER_NAME}
-    ports:
-      - ${BASYX_HOST_PORT}:${BASYX_CONTAINER_PORT}
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASX/pom.xml b/components/basys.components/basyx.components.docker/basyx.components.AASX/pom.xml
deleted file mode 100644
index 2e985e6..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.AASX/pom.xml
+++ /dev/null
@@ -1,89 +0,0 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0" 
-	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
-	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  
- 
-  <parent>
-		<groupId>org.eclipse.basyx</groupId>
-		<artifactId>basyx.components.docker</artifactId>
-		<version>0.0.1-SNAPSHOT</version>
-    </parent>
-	
-	<artifactId>basyx.components.AASX</artifactId>
-	<name>BaSyx AASX Docker Component</name>
-	
-	<properties>
-		<!--  
-			basyx.components.executable is the executable class with the definition of the public void main(String[]).
-			It is needed when building the jar in the maven-jar-plugin (see basyx.components.docker/pom.xml) 
-		-->
-		<basyx.components.executable>org.eclipse.basyx.components.executable.AASXExecutable</basyx.components.executable>
-	</properties>
-	
-	<packaging>jar</packaging>
-	
-	<!-- Define additional plugins that are not included by default -->
-	<!-- Plugin configuration is done in parent project(s) -->
-	<build>
-		<plugins>
-			<!-- Attach sources to jar file -->
-			<plugin>
-				<groupId>org.apache.maven.plugins</groupId>
-				<artifactId>maven-source-plugin</artifactId>
-			</plugin>
-		</plugins>
-	</build>
-	
-	<dependencies>
-		<!-- This component is based on the xmlAAS component -->
-		<dependency>
-			<groupId>org.eclipse.basyx</groupId>
-			<artifactId>basyx.components.xmlAAS</artifactId>
-			<version>${project.version}</version>
-		</dependency>
-	</dependencies>
-	
-	<profiles>
-		<profile>
-			<!-- 
-				"Docker" profile - do not build & install docker images by default
-				Run "mvn install -Pdocker" in order to include docker  
-			-->
-			<id>docker</id>
-			<build>
-				<plugins>
-					<!-- Read maven properties from file -->
-					<plugin>
-						<groupId>org.codehaus.mojo</groupId>
-						<artifactId>properties-maven-plugin</artifactId>
-					</plugin>
-				
-					<!-- Copy the dependencies necessary to run the jar -->
-					<plugin>
-						<groupId>org.apache.maven.plugins</groupId>
-						<artifactId>maven-dependency-plugin</artifactId>
-					</plugin>
-				
-					<!-- Build the docker image -->
-					<plugin>
-						<groupId>com.spotify</groupId>
-						<artifactId>dockerfile-maven-plugin</artifactId>
-					</plugin>
-				
-					<!-- Create integration test environment -->
-					<plugin>
-						<groupId>com.dkanejs.maven.plugins</groupId>
-						<artifactId>docker-compose-maven-plugin</artifactId>
-					</plugin>
-					
-					<!-- Run integration tests -->
-					<plugin>    
-						<groupId>org.apache.maven.plugins</groupId>
-						<artifactId>maven-failsafe-plugin</artifactId>
-					</plugin>
-				</plugins>
-			</build>
-		</profile>
-	</profiles>
-</project>
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASX/src/main/java/org/eclipse/basyx/components/AASXComponent.java b/components/basys.components/basyx.components.docker/basyx.components.AASX/src/main/java/org/eclipse/basyx/components/AASXComponent.java
deleted file mode 100644
index f2abd28..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.AASX/src/main/java/org/eclipse/basyx/components/AASXComponent.java
+++ /dev/null
@@ -1,79 +0,0 @@
-package org.eclipse.basyx.components;
-
-
-import java.io.IOException;
-import java.net.URISyntaxException;
-import java.util.Set;
-
-import javax.servlet.ServletException;
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.apache.catalina.servlets.DefaultServlet;
-import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
-import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
-import org.eclipse.basyx.components.aasx.AASXPackageManager;
-import org.eclipse.basyx.components.servlet.aas.AASBundleServlet;
-import org.eclipse.basyx.support.bundle.AASBundle;
-import org.eclipse.basyx.vab.protocol.http.server.AASHTTPServer;
-import org.eclipse.basyx.vab.protocol.http.server.BaSyxContext;
-import org.xml.sax.SAXException;
-
-/**
- * A component that takes an AASX file and provides it via an HTTP server
- * 
- * @author schnicke, espen
- *
- */
-public class AASXComponent extends XMLAASComponent {
-	public AASXComponent(String hostName, int port, String path, String docBasePath, String aasxPath,
-			String registryUrl) throws IOException, ParserConfigurationException, SAXException, URISyntaxException {
-		super(hostName, port, path, docBasePath);
-
-		// Instantiate the aasx package manager
-		AASXPackageManager packageManager = new AASXPackageManager(aasxPath);
-
-		// Unpack the files referenced by the aas
-		packageManager.unzipRelatedFiles(aasxPath);
-
-		// Retrieve the aas from the package
-		Set<AASBundle> aasBundles = packageManager.retrieveAASBundles();
-
-		setAASBundle(aasBundles);
-		setRegistryUrl(registryUrl);
-	}
-
-	/**
-	 * Starts the AASX component at http://${hostName}:${port}/${path}
-	 * 
-	 * @param hostName
-	 * @param port
-	 * @param path
-	 * @param docBasePath
-	 * @throws ServletException
-	 * @throws IOException
-	 * @throws SAXException
-	 * @throws ParserConfigurationException
-	 */
-	@Override
-	public void startComponent() {
-		// Init HTTP context and add an XMLAAServlet according to the configuration
-
-		BaSyxContext context = new BaSyxContext(path, docBasePath, hostName, port);
-		// Create the Servlet for aas
-		context.addServletMapping("/*", new AASBundleServlet(aasBundles));
-		context.addServletMapping("/aasx/*", new DefaultServlet());
-		server = new AASHTTPServer(context);
-
-		// logger.info("Start the server...");
-		server.start();
-
-		if (registryUrl != null && !registryUrl.isEmpty()) {
-			// logger.info("Registering AAS at registry \"" + registryUrl + "\"...");
-			AASRegistryProxy registryProxy = new AASRegistryProxy(registryUrl);
-			Set<AASDescriptor> descriptors = retrieveDescriptors();
-			descriptors.stream().forEach(registryProxy::register);
-		} else {
-			// logger.info("No registry specified, skipped registration");
-		}
-	}
-}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASX/src/main/java/org/eclipse/basyx/components/aasx/AASXPackageManager.java b/components/basys.components/basyx.components.docker/basyx.components.AASX/src/main/java/org/eclipse/basyx/components/aasx/AASXPackageManager.java
deleted file mode 100644
index 485b391..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.AASX/src/main/java/org/eclipse/basyx/components/aasx/AASXPackageManager.java
+++ /dev/null
@@ -1,376 +0,0 @@
-package org.eclipse.basyx.components.aasx;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Set;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipInputStream;
-
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.apache.commons.io.IOUtils;
-import org.eclipse.basyx.components.configuration.BaSyxConfiguration;
-import org.eclipse.basyx.components.xml.XMLAASBundleFactory;
-import org.eclipse.basyx.support.bundle.AASBundle;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-import org.xml.sax.SAXException;
-/**
- * The AASX package converter converts a aasx package into a list of aas, a list
- * of submodels a list of assets, a list of Concept descriptions
- * 
- * The aas provides the references to the submodels and assets
- * 
- * @author zhangzai
- *
- */
-public class AASXPackageManager {
-
-
-	/**
-	 * Path to the AASX package
-	 */
-	private String aasxPath;
-
-	/**
-	 * AAS bundle factory
-	 */
-	private XMLAASBundleFactory bundleFactory;
-
-	/**
-	 * Logger
-	 */
-	private static Logger logger = LoggerFactory.getLogger(AASXPackageManager.class);
-
-	/**
-	 * Constructor
-	 */
-	public AASXPackageManager(String path) {
-		aasxPath = path;
-	}
-
-	public Set<AASBundle> retrieveAASBundles() throws IOException, ParserConfigurationException, SAXException {
-		bundleFactory = new XMLAASBundleFactory(getXMLResourceString(aasxPath));
-		
-		return bundleFactory.create();
-	}
-
-	/**
-	 * Find the path of the aas-xml file
-	 * 
-	 * @param stream - Stream of the aasx package
-	 * @return Path of the aas xml file, empty string if not found
-	 * @throws IOException
-	 * @throws ParserConfigurationException
-	 * @throws SAXException
-	 */
-	private String findAASXml(ZipInputStream stream) throws IOException, ParserConfigurationException, SAXException {
-		String path = "";
-		// find the entry of the aasx
-		for (ZipEntry entry; (entry = stream.getNextEntry()) != null;) {
-
-			// get name of the entry
-			String name = entry.getName();
-
-			// find the relationship file in the directory /aasx/_rels/aas_origin.rels
-			if (!entry.isDirectory() && name.startsWith("aasx/_rels")) {
-				// find the file aasx-origin.rels
-				if (name.endsWith("aasx-origin.rels")) {
-					// Get path of the aas xml
-					String aasXmlPath = findAASXMLAddress(stream);
-					if (!aasXmlPath.isEmpty()) {
-						path = aasXmlPath;
-						break;
-					}
-				}
-			}
-		}
-		return path;
-	}
-
-	/**
-	 * Get entry of a file
-	 * 
-	 * @param filename - name of a file with path
-	 * @return a file entry
-	 * @throws IOException
-	 */
-	private ZipInputStream returnFileEntryStream(String filename, ZipInputStream stream) throws IOException {
-		ZipInputStream str = null;
-		if (filename.startsWith("/")) {
-			filename = filename.substring(1);
-		}
-
-		// get all entries of the aasx
-		for (ZipEntry e; (e = stream.getNextEntry()) != null;) {
-			// get name of the entry
-			String name = e.getName();
-			if (name.equals(filename)) {
-				str = stream;
-				break;
-			}
-		}
-		return str;
-	}
-
-	/**
-	 * Parse the relationship file and find the path of the aas-XML file describing
-	 * the aas
-	 * 
-	 * @param ins - input stream of this relationship file
-	 * @return path of the aas-xml file
-	 * @throws ParserConfigurationException
-	 * @throws SAXException
-	 * @throws IOException
-	 */
-	private String findAASXMLAddress(InputStream ins) throws ParserConfigurationException, SAXException, IOException {
-		String path = "";
-
-		// create the XML document parser
-		DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
-		DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
-		Document doc = dBuilder.parse(ins);
-		doc.getDocumentElement().normalize();
-
-		// Get the tag with "Relationships"
-		logger.info("Root element :" + doc.getDocumentElement().getNodeName());
-		NodeList relList = doc.getElementsByTagName("Relationship");
-
-		// If there is only 1 relationship pointing to the aas-xml file, this should be
-		// the case
-		if (relList.getLength() == 1) {
-			Node first = relList.item(0);
-
-			if (first.getNodeType() == Node.ELEMENT_NODE) {
-				logger.info("\nCurrent Element :" + first.getNodeName());
-				// get the target file path
-				String targetFile = ((Element) first).getAttribute("Target");
-				String type = ((Element) first).getAttribute("Type");
-
-				// validate the relationship type
-				if (type.endsWith("aas-spec")) {
-					logger.info("target file name : " + targetFile);
-					path = targetFile;
-				}
-			}
-		}
-		return path;
-	}
-
-	/**
-	 * Return the Content of the xml file in the aasx-package as String
-	 * 
-	 * @param filePath - path to the aasx package
-	 * @return Content of XML as String
-	 * @throws IOException
-	 * @throws ParserConfigurationException
-	 * @throws SAXException
-	 */
-	private String getXMLResourceString(String filePath) throws IOException, ParserConfigurationException, SAXException {
-		String aasXmlPath;
-		// Create the zip input stream
-		try (ZipInputStream stream = new ZipInputStream(BaSyxConfiguration.getResourceStream(filePath))) {
-
-			// find the path of the aas xml
-			aasXmlPath = this.findAASXml(stream);
-		}
-
-		try (ZipInputStream stream = new ZipInputStream(BaSyxConfiguration.getResourceStream(filePath))) {
-			// Find the entry of the aas xml
-			ZipInputStream streamPointingToEntry = this.returnFileEntryStream(aasXmlPath, stream);
-
-			// create the xml-converter with the input stream
-			String text = IOUtils.toString(streamPointingToEntry, StandardCharsets.UTF_8.name());
-			return text;
-		}
-	}
-
-	/**
-	 * Load the referenced filepaths in the submodels such as PDF, PNG files from
-	 * the package
-	 * 
-	 * @return a map of the folder name and folder path, the folder holds the files
-	 * @throws IOException
-	 * @throws SAXException
-	 * @throws ParserConfigurationException
-	 * 
-	 */
-	private List<String> parseReferencedFilePathsFromAASX(String aasxFilePath)
-			throws IOException, ParserConfigurationException, SAXException {
-		String xmlPath;
-		logger.info("AASX filepath: " + aasxFilePath);
-		try (ZipInputStream stream = new ZipInputStream(BaSyxConfiguration.getResourceStream(aasxFilePath))) {
-			// find the aasx xml file
-			xmlPath = this.findAASXml(stream);
-		}
-
-		try (ZipInputStream stream = new ZipInputStream(BaSyxConfiguration.getResourceStream(aasxFilePath))) {
-			// find the relationship file next to the aas xml file
-			String[] xmlPathParts = xmlPath.split("/");
-			String relPath = xmlPath.substring(0, xmlPath.lastIndexOf("/")) + "/_rels/" + xmlPathParts[xmlPathParts.length - 1] + ".rels";
-
-			// Find the entry of the xml .rel file
-			ZipInputStream streamPointingToEntry = this.returnFileEntryStream(relPath, stream);
-
-			// Return all files referenced in this relationship file
-			return parseReferencedFilePathsFromRelationship(streamPointingToEntry);
-		}
-	}
-
-	/**
-	 * Unzips all files referenced by the aasx file according to its relationships
-	 * 
-	 * @param filePath - path the AASX
-	 * 
-	 * @throws IOException
-	 * @throws SAXException
-	 * @throws ParserConfigurationException
-	 * @throws URISyntaxException
-	 */
-	public void unzipRelatedFiles(String aasxFilePath)
-			throws IOException, ParserConfigurationException, SAXException, URISyntaxException {
-		// load folder which stores the files
-		List<String> files = parseReferencedFilePathsFromAASX(aasxFilePath);
-		for (String filePath : files) {
-			// name of the folder
-			unzipFile(filePath, aasxPath);
-		}
-	}
-
-	/**
-	 * Create a folder to hold the unpackaged files The folder has the path
-	 * \target\classes\docs
-	 * 
-	 * @throws IOException
-	 * @throws URISyntaxException
-	 */
-	private Path getRootFolder() throws IOException, URISyntaxException {
-		URI uri = AASXPackageManager.class.getProtectionDomain().getCodeSource().getLocation().toURI();
-		URI parent = new File(uri).getParentFile().toURI();
-		return Paths.get(parent);
-	}
-
-	/**
-	 * unzip the file folders
-	 * 
-	 * @param filePath - path of the file in the aasx to unzip
-	 * @param aasxPath    - aasx path
-	 * @throws IOException
-	 * @throws URISyntaxException
-	 */
-	private void unzipFile(String filePath, String aasxPath)
-			throws IOException, URISyntaxException {
-		// Create destination directory
-		if (filePath.startsWith("/")) {
-			filePath = filePath.substring(1);
-		}
-		logger.info("Unzipping " + filePath + " to root folder:");
-		String relativePath = filePath.substring(0, filePath.lastIndexOf("/"));
-		Path rootPath = getRootFolder();
-		Path destDir = rootPath.resolve(relativePath);
-		logger.info("Unzipping to " + destDir);
-		Files.createDirectories(destDir);
-
-		// create buffer for the folder binary
-		byte[] buffer = new byte[1024];
-
-		// Find the file with the "filePath"
-		try (ZipInputStream stream = new ZipInputStream(BaSyxConfiguration.getResourceStream(aasxPath))) {
-			ZipEntry zipEntry = stream.getNextEntry();
-			while (zipEntry != null) {
-				if (!zipEntry.isDirectory() && zipEntry.getName().contains(filePath)) {
-					// Create the file object in the destination directory
-					File newFile = newFile(destDir.toFile(), zipEntry);
-
-					// Create the file output stream
-					try (FileOutputStream fos = new FileOutputStream(newFile)) {
-						int len;
-						// Write the binary to the file
-						while ((len = stream.read(buffer)) > 0) {
-							fos.write(buffer, 0, len);
-						}
-					}
-					return;
-				}
-				zipEntry = stream.getNextEntry();
-			}
-		}
-	}
-
-	/**
-	 * Preventing Zip Slip, create a file
-	 * 
-	 * @param destinationDir
-	 * @param zipEntry
-	 * @return
-	 * @throws IOException
-	 */
-	private File newFile(File destinationDir, ZipEntry zipEntry) throws IOException {
-		int i = zipEntry.getName().lastIndexOf("/");
-		String filename = zipEntry.getName().substring(i);
-
-		File destFile = new File(destinationDir, filename);
-
-		String destDirPath = destinationDir.getCanonicalPath();
-		String destFilePath = destFile.getCanonicalPath();
-
-		if (!destFilePath.startsWith(destDirPath + File.separator)) {
-			throw new IOException("Entry is outside of the target dir: " + zipEntry.getName());
-		}
-
-		return destFile;
-	}
-	
-	/**
-	 * Find path of the referenced file with reference type aas-suppl
-	 * 
-	 * @param insRelFile - the input stream of the relationship file
-	 * @return
-	 * @throws ParserConfigurationException
-	 * @throws SAXException
-	 * @throws IOException
-	 */
-	private List<String> parseReferencedFilePathsFromRelationship(InputStream insRelFile)
-			throws ParserConfigurationException, SAXException, IOException {
-		List<String> files = new ArrayList<>();
-
-		// create the XML document parser
-		DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
-		DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
-		Document doc = dBuilder.parse(insRelFile);
-		doc.getDocumentElement().normalize();
-
-		// Get the tag with "Relationships"
-		NodeList relList = doc.getElementsByTagName("Relationship");
-		for (int i = 0; i < relList.getLength(); i++) {
-			Node node = relList.item(i);
-			if (node.getNodeType() == Node.ELEMENT_NODE) {
-				// get the target file path
-				String targetFile = ((Element) node).getAttribute("Target");
-				String type = ((Element) node).getAttribute("Type");
-
-				// validate the relationship type
-				if (type.endsWith("aas-suppl")) {
-					files.add(targetFile);
-				}
-			}
-		}
-		return files;
-	}
-}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASX/src/main/java/org/eclipse/basyx/components/executable/AASXExecutable.java b/components/basys.components/basyx.components.docker/basyx.components.AASX/src/main/java/org/eclipse/basyx/components/executable/AASXExecutable.java
deleted file mode 100644
index 8e1e137..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.AASX/src/main/java/org/eclipse/basyx/components/executable/AASXExecutable.java
+++ /dev/null
@@ -1,56 +0,0 @@
-package org.eclipse.basyx.components.executable;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.URISyntaxException;
-
-import javax.servlet.ServletException;
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.eclipse.basyx.components.AASXComponent;
-import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.xml.sax.SAXException;
-
-/**
- * Starts an HTTP server providing multiple AAS and submodels as described in
- * the AASX package file specified in the properties file <br />
- * They are made available at <i>localhost:4000/aasx/$aasId/aas</i><br />
- * <br />
- * <b>Please note:</b> Neither the AASs nor the Submodels are added to the
- * registry. Additionally, the Submodel descriptors inside the AAS are missing.
- * <br />
- * There reason for this is, that the executable does not know about the outside
- * context (e.g. docker, ...)!
- * 
- * @author zhang
- */
-public class AASXExecutable {
-	private static Logger logger = LoggerFactory.getLogger(AASXExecutable.class);
-
-	public static void main(String[] args) throws IOException, ParserConfigurationException, SAXException, URISyntaxException, ServletException {
-		logger.info("Starting BaSyx AASX component");
-
-		// Load configuration
-		BaSyxContextConfiguration config = new BaSyxContextConfiguration();
-		if (args.length > 0 && args[0] instanceof String) {
-			// file path available? => load configs from file
-			config.loadFromFile(args[0]);
-		} else {
-			// fallback: load default configs (in resources)
-			config.loadFromResource(BaSyxContextConfiguration.DEFAULT_CONFIG_PATH);
-		}
-
-		// In addition to the context for the AAS, also the registryUrl can be specified
-		String registryUrl = config.getProperty("registry");
-
-		String rootPath = new File(AASXExecutable.class.getProtectionDomain().getCodeSource().getLocation().toURI())
-				.getParentFile().getPath();
-		String docPath = rootPath + config.getDocBasePath();
-		// Get the path to the doc base path
-		AASXComponent component = new AASXComponent(config.getHostname(), config.getPort(), config.getContextPath(),
-				docPath, config.getProperty("aasxPath"), registryUrl);
-		component.startComponent();
-	}
-}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASX/src/main/java/org/eclipse/basyx/components/servlets/AASXAASServlet.java b/components/basys.components/basyx.components.docker/basyx.components.AASX/src/main/java/org/eclipse/basyx/components/servlets/AASXAASServlet.java
deleted file mode 100644
index 75e7b67..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.AASX/src/main/java/org/eclipse/basyx/components/servlets/AASXAASServlet.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package org.eclipse.basyx.components.servlets;
-
-import java.io.IOException;
-
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.eclipse.basyx.components.aasx.AASXPackageManager;
-import org.eclipse.basyx.components.servlet.aas.AASBundleServlet;
-import org.xml.sax.SAXException;
-
-/**
- * It generates the AAS-bundle using AASX package manager. It also maps the AAS
- * to servlet and adds the submodels, assets and concept descriptors to the AAS.
- * 
- * 
- * @author zhangzai
- */
-public class AASXAASServlet extends AASBundleServlet {
-	private static final long serialVersionUID = -3487515646027982620L;
-
-
-
-	public AASXAASServlet(String filePath) throws ParserConfigurationException, SAXException, IOException {
-		super(new AASXPackageManager(filePath).retrieveAASBundles());
-
-	}
-}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASX/src/main/resources/context.properties b/components/basys.components/basyx.components.docker/basyx.components.AASX/src/main/resources/context.properties
deleted file mode 100644
index 309a541..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.AASX/src/main/resources/context.properties
+++ /dev/null
@@ -1,5 +0,0 @@
-contextPath=/
-contextHostname=localhost
-contextPort=4000
-aasxPath=aasx/01_Festo.aasx
-contextDocPath=/
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASX/src/main/resources/logback.xml b/components/basys.components/basyx.components.docker/basyx.components.AASX/src/main/resources/logback.xml
deleted file mode 100644
index 86341d6..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.AASX/src/main/resources/logback.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
- 
-<configuration>
- 
-  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
-    
-    <!-- Example for a filter, which removes all entries not containing "[TEST]" in the message. -->
-    
-    <!--<filter class="ch.qos.logback.core.filter.EvaluatorFilter">      
-      <evaluator>
-        <expression>return message.contains("[TEST]");</expression>
-      </evaluator>
-      <OnMismatch>DENY</OnMismatch>
-      <OnMatch>NEUTRAL</OnMatch>
-    </filter>-->
-  
-    <encoder>
-      <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{5} - %msg%n</pattern>
-    </encoder>
-  </appender>
-  
-  <root level="INFO">          
-    <appender-ref ref="STDOUT" />
-  </root>  
-   
-</configuration>
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASX/src/test/java/org/eclipse/basyx/regression/aasx/AASXSuite.java b/components/basys.components/basyx.components.docker/basyx.components.AASX/src/test/java/org/eclipse/basyx/regression/aasx/AASXSuite.java
deleted file mode 100644
index bd2c82e..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.AASX/src/test/java/org/eclipse/basyx/regression/aasx/AASXSuite.java
+++ /dev/null
@@ -1,176 +0,0 @@
-package org.eclipse.basyx.regression.aasx;
-
-import static org.junit.Assert.assertEquals;
-
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.Map;
-
-import javax.ws.rs.client.Client;
-import javax.ws.rs.client.ClientBuilder;
-import javax.ws.rs.client.Invocation;
-import javax.ws.rs.client.WebTarget;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-
-import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
-import org.eclipse.basyx.aas.metamodel.connected.ConnectedAssetAdministrationShell;
-import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
-import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
-import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
-import org.eclipse.basyx.aas.registration.api.IAASRegistryService;
-import org.eclipse.basyx.aas.registration.memory.InMemoryRegistry;
-import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
-import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
-import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
-import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElementCollection;
-import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IFile;
-import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.ConnectedSubmodelElementCollection;
-import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.dataelement.ConnectedFile;
-import org.eclipse.basyx.vab.protocol.api.IConnectorProvider;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
-import org.junit.Before;
-import org.junit.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Suite for testing that the XMLAAS servlet is set up correctly. The tests here
- * can be used by the servlet test itself and the integration test
- * 
- * @author schnicke, espen
- *
- */
-public class AASXSuite {
-	private static Logger logger = LoggerFactory.getLogger(AASXSuite.class);
-
-	protected IAASRegistryService aasRegistry;
-
-	protected static final String aasShortId = "Festo_3S7PM0CP4BD";
-	protected static final IIdentifier aasId = new ModelUrn("smart.festo.com/demo/aas/1/1/454576463545648365874");
-	protected static final IIdentifier smId = new ModelUrn("www.company.com/ids/sm/4343_5072_7091_3242");
-	protected static final String smShortId = "Nameplate";
-
-	// Has to be individualized by each test inheriting from this suite
-	protected static String aasEndpoint;
-	protected static String smEndpoint;
-	protected static String rootEndpoint;
-
-	private ConnectedAssetAdministrationShellManager manager;
-
-	// create a REST client
-	private Client client = ClientBuilder.newClient();
-
-	/**
-	 * Before each test, a dummy registry is created and an AAS is added in the
-	 * registry
-	 */
-	@Before
-	public void setUp() {
-		// Create a dummy registry to test integration of XML AAS
-		aasRegistry = new InMemoryRegistry();
-		AASDescriptor descriptor = new AASDescriptor(aasShortId, aasId, aasEndpoint);
-		descriptor.addSubmodelDescriptor(new SubmodelDescriptor(smShortId, smId, smEndpoint));
-		aasRegistry.register(descriptor);
-
-		// Create a ConnectedAssetAdministrationShell using a
-		// ConnectedAssetAdministrationShellManager
-		IConnectorProvider connectorProvider = new HTTPConnectorProvider();
-		manager = new ConnectedAssetAdministrationShellManager(aasRegistry, connectorProvider);
-	}
-
-	@Test
-	public void testGetSingleAAS() throws Exception {
-		ConnectedAssetAdministrationShell connectedAssetAdministrationShell = getConnectedAssetAdministrationShell();
-		assertEquals(aasShortId, connectedAssetAdministrationShell.getIdShort());
-	}
-
-	@Test
-	public void testGetSingleSubmodel() throws Exception {
-		ISubModel subModel = getConnectedSubmodel();
-		assertEquals(smShortId, subModel.getIdShort());
-	}
-
-	@Test
-	public void testGetSingleModule() throws Exception {
-		checkFile("aasx/Nameplate/marking_rcm.jpg");
-
-		// Get the submdoel nameplate
-		ISubModel nameplate = getConnectedSubmodel();
-		// Get the submodel element collection marking_rcm
-		ConnectedSubmodelElementCollection marking_rcm = (ConnectedSubmodelElementCollection) nameplate.getSubmodelElements().get("Marking_RCM");
-		Collection<ISubmodelElement> values = marking_rcm.getValue();
-
-		// navigate to the File element
-		Iterator<ISubmodelElement> iter = values.iterator();
-		while (iter.hasNext()) {
-			ISubmodelElement element = iter.next();
-			if (element instanceof ConnectedFile) {
-				ConnectedFile connectedFile = (ConnectedFile) element;
-				// get value of the file element
-
-				String fileurl = connectedFile.getValue();
-				assertEquals("http://localhost:4000/aasx/docs/marking_rcm.jpg", fileurl);
-			}
-		}
-	}
-
-	@Test
-	public void testAllFiles() throws Exception {
-		logger.info("Checking all files");
-		ConnectedAssetAdministrationShell aas = getConnectedAssetAdministrationShell();
-		logger.info("AAS idShort: " + aas.getIdShort());
-		logger.info("AAS identifier: " + aas.getIdentification().getId());
-		Map<String, ISubModel> submodels = aas.getSubModels();
-		logger.info("# Submodels: " + submodels.size());
-		for (ISubModel sm : submodels.values()) {
-			logger.info("Checking submodel: " + sm.getIdShort());
-			checkElementCollectionFiles(sm.getSubmodelElements().values());
-		}
-
-	}
-
-	private void checkElementCollectionFiles(Collection<ISubmodelElement> elements) {
-		for (ISubmodelElement element : elements) {
-			if (element instanceof IFile) {
-				String fileUrl = ((IFile) element).getValue();
-				checkFile(fileUrl);
-			} else if (element instanceof ISubmodelElementCollection) {
-				ISubmodelElementCollection col = (ISubmodelElementCollection) element;
-				checkElementCollectionFiles(col.getValue());
-			}
-		}
-	}
-
-	private void checkFile(String relativePath) {
-		// connect to the url of the aas
-		WebTarget webTarget = client.target(rootEndpoint);
-		// go to the path of the file
-		WebTarget fileTarget = webTarget.path(relativePath);
-		logger.info("Checking file: " + relativePath);
-		Invocation.Builder invocationBuilder = fileTarget.request(MediaType.APPLICATION_JSON);
-		Response response = invocationBuilder.get();
-		// validate the response
-		assertEquals(200, response.getStatus());
-	}
-
-	/**
-	 * Gets the connected Asset Administration Shell
-	 * 
-	 * @return connected AAS
-	 * @throws Exception
-	 */
-	private ConnectedAssetAdministrationShell getConnectedAssetAdministrationShell() throws Exception {
-		return manager.retrieveAAS(aasId);
-	}
-
-	/**
-	 * Gets the connected Submodel
-	 * 
-	 * @return connected SM
-	 * @throws Exception
-	 */
-	private ISubModel getConnectedSubmodel() {
-		return manager.retrieveSubModel(aasId, smId);
-	}
-}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASX/src/test/java/org/eclipse/basyx/regression/aasx/ITInAASX.java b/components/basys.components/basyx.components.docker/basyx.components.AASX/src/test/java/org/eclipse/basyx/regression/aasx/ITInAASX.java
deleted file mode 100644
index 8d417ae..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.AASX/src/test/java/org/eclipse/basyx/regression/aasx/ITInAASX.java
+++ /dev/null
@@ -1,70 +0,0 @@
-package org.eclipse.basyx.regression.aasx;
-
-import javax.ws.rs.ProcessingException;
-import javax.ws.rs.client.Client;
-import javax.ws.rs.client.ClientBuilder;
-import javax.ws.rs.client.Invocation;
-import javax.ws.rs.client.WebTarget;
-import javax.ws.rs.core.MediaType;
-
-import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
-import org.eclipse.basyx.components.configuration.BaSyxDockerConfiguration;
-import org.junit.BeforeClass;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * A Test case for accessing an element of an aas which is hosted on Docker
- * 
- *
- */
-public class ITInAASX extends AASXSuite {
-	private static Logger logger = LoggerFactory.getLogger(ITInAASX.class);
-
-	@BeforeClass
-	public static void setUpClass() {
-		logger.info("Running integration test...");
-
-		logger.info("Loading servlet configuration");
-		// Load the servlet configuration inside of the docker configuration from
-		// properties file
-		BaSyxContextConfiguration contextConfig = new BaSyxContextConfiguration();
-		contextConfig.loadFromResource(BaSyxContextConfiguration.DEFAULT_CONFIG_PATH);
-
-		// Load the docker environment configuration from properties file
-		logger.info("Loading docker configuration");
-		BaSyxDockerConfiguration dockerConfig = new BaSyxDockerConfiguration();
-		dockerConfig.loadFromResource(BaSyxDockerConfiguration.DEFAULT_CONFIG_PATH);
-
-		rootEndpoint = "http://localhost:" + dockerConfig.getHostPort() + contextConfig.getContextPath() + "/";
-		aasEndpoint = rootEndpoint + aasShortId + "/aas";
-		smEndpoint = rootEndpoint + aasShortId + "/aas/submodels/" + smShortId + "/submodel";
-
-		waitUntilReady();
-
-		logger.info("AAS URL for integration test: " + aasEndpoint);
-	}
-
-	/**
-	 * Waits for at most 4s until the container is ready
-	 */
-	private static void waitUntilReady() {
-		Client client = ClientBuilder.newClient();
-		WebTarget webTarget = client.target(rootEndpoint);
-		Invocation.Builder invocationBuilder = webTarget.request(MediaType.APPLICATION_JSON);
-		for (int i = 0; i < 20; i++) {
-			try {
-				invocationBuilder.get();
-				return;
-			} catch (ProcessingException e) {
-				// retry
-				try {
-					Thread.sleep(200);
-				} catch (InterruptedException e1) {
-					e1.printStackTrace();
-				}
-			}
-		}
-	}
-
-}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASX/src/test/java/org/eclipse/basyx/regression/aasx/TestAASX.java b/components/basys.components/basyx.components.docker/basyx.components.AASX/src/test/java/org/eclipse/basyx/regression/aasx/TestAASX.java
deleted file mode 100644
index 71d3eab..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.AASX/src/test/java/org/eclipse/basyx/regression/aasx/TestAASX.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package org.eclipse.basyx.regression.aasx;
-
-import java.io.IOException;
-import java.net.URISyntaxException;
-
-import javax.servlet.ServletException;
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
-import org.eclipse.basyx.components.executable.AASXExecutable;
-import org.junit.BeforeClass;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.xml.sax.SAXException;
-
-/**
- * Test accessing to AAS using basys aas SDK
- * 
- * @author zhangzai
- *
- */
-public class TestAASX extends AASXSuite {
-	private static Logger logger = LoggerFactory.getLogger(TestAASX.class);
-
-	@BeforeClass
-	public static void setUpClass() throws ParserConfigurationException, SAXException, IOException, URISyntaxException, ServletException {
-		AASXExecutable.main(new String[] {});
-
-		BaSyxContextConfiguration config = new BaSyxContextConfiguration();
-		config.loadFromResource(BaSyxContextConfiguration.DEFAULT_CONFIG_PATH);
-
-		rootEndpoint = "http://" + config.getHostname() + ":" + config.getPort() + "/" + config.getContextPath() + "/";
-		aasEndpoint = rootEndpoint + aasShortId + "/aas";
-		smEndpoint = rootEndpoint + aasShortId + "/aas/submodels/" + smShortId + "/submodel";
-		logger.info("AAS URL for servlet test: " + aasEndpoint);
-	}
-}
-
-
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASX/src/test/java/org/eclipse/basyx/regression/aasx/TestAASXPackageManager.java b/components/basys.components/basyx.components.docker/basyx.components.AASX/src/test/java/org/eclipse/basyx/regression/aasx/TestAASXPackageManager.java
deleted file mode 100644
index 89225de..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.AASX/src/test/java/org/eclipse/basyx/regression/aasx/TestAASXPackageManager.java
+++ /dev/null
@@ -1,267 +0,0 @@
-package org.eclipse.basyx.regression.aasx;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
-import org.eclipse.basyx.components.aasx.AASXPackageManager;
-import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
-import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
-import org.eclipse.basyx.submodel.metamodel.api.reference.IKey;
-import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
-import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.support.bundle.AASBundle;
-import org.junit.Before;
-import org.junit.Test;
-import org.xml.sax.SAXException;
-
-/**
- * J-Unit tests for AASx package explorer. This test checks the parsing of aas,
- * submodels, assets and concept-descriptions. it also checks whether the aas
- * have correct references to the asets and submodels
- * 
- * @author zhangzai
- *
- */
-public class TestAASXPackageManager {
-	/**
-	 * path to the aasx package
-	 */
-	private String aasxPath = "aasx/01_Festo.aasx";
-
-	/**
-	 * the aasx package converter
-	 */
-	private AASXPackageManager packageConverter;
-
-	/**
-	 * this string array is used to check the refs to submodels of aas
-	 */
-	private String[] submodelids = { "www.company.com/ids/sm/6053_5072_7091_5102", "smart.festo.com/demo/sm/instance/1/1/13B7CCD9BF7A3F24", "www.company.com/ids/sm/4343_5072_7091_3242", "www.company.com/ids/sm/2543_5072_7091_2660",
-			"www.company.com/ids/sm/6563_5072_7091_4267"
-
-	};
-
-	/**
-	 * AAS bundle which will be generated by the XMLAASBundleFactory
-	 */
-	private Set<AASBundle> aasBundles;
-
-	/**
-	 * Submodels parsed by the converter
-	 */
-	private Set<ISubModel> submodels;
-
-	/**
-	 * Initialize the AASX package converter
-	 */
-	@Before
-	public void setup() {
-		// Create the aasx package converter with the path to the aasx package
-		packageConverter = new AASXPackageManager(aasxPath);
-	}
-
-	/**
-	 * Test parsing of aas, assets, submodels and concept-descriptions
-	 */
-	@Test
-	public void testCheckAasxConverter() {
-		// Parse aas from the XML and create the AAS Bundle with refs to submodels
-		try {
-			aasBundles = packageConverter.retrieveAASBundles();
-		} catch (ParserConfigurationException | SAXException | IOException e) {
-			e.printStackTrace();
-		}
-
-		// check the information in the aas bundles
-		checkAASs(aasBundles);
-
-		// Check the submodels
-		checkSubmodels(submodels);
-	}
-
-	/**
-	 * Check the parsed aas with expected ones
-	 * 
-	 * @param aasList
-	 */
-	private void checkAASs(Set<AASBundle> aasBundles) {
-		assertEquals(2, aasBundles.size());
-
-		IAssetAdministrationShell aas = null;
-
-		// select the AAS with a specific ID from the list
-		Optional<AASBundle> testAASBundleOptional = aasBundles.stream().filter(b -> b.getAAS().getIdShort().equals("Festo_3S7PM0CP4BD")).findFirst();
-		// verify there exist one aas with this ID
-		assertTrue(testAASBundleOptional.isPresent());
-
-		// Get the aasbundle from the filtered results
-		AASBundle testAASBundle = testAASBundleOptional.get();
-		aas = testAASBundle.getAAS();
-
-		// get submodels of this aas
-		submodels = testAASBundle.getSubmodels();
-
-		// verify short id
-		assertEquals("Festo_3S7PM0CP4BD", aas.getIdShort());
-		assertEquals("CONSTANT", aas.getCategory());
-
-		assertEquals("", aas.getDescription().get("EN"));
-		assertEquals("", aas.getDescription().get("DE"));
-
-		// verify id and id-type
-		assertEquals("smart.festo.com/demo/aas/1/1/454576463545648365874", aas.getIdentification().getId());
-		assertEquals(IdentifierType.IRI, aas.getIdentification().getIdType());
-
-
-		// Get submodel references
-		Collection<IReference> references = aas.getSubmodelReferences();
-
-		// this aas has 5 submodels
-		assertEquals(5, references.size());
-		List<IReference> referencelist = new ArrayList<>();
-		referencelist.addAll(references);
-
-		// sort the list for later assertion
-		// list is sorted by the last two characters of the id
-		referencelist.sort((x, y) -> {
-			String idx = x.getKeys().get(0).getValue();
-			String idy = y.getKeys().get(0).getValue();
-
-			String idx_end = idx.substring(idx.length() - 2);
-			int idxint = Integer.parseInt(idx_end);
-			String idy_end = idy.substring(idy.length() - 2);
-			int idyint = Integer.parseInt(idy_end);
-
-			return idxint - idyint;
-
-		});
-
-		// get First submodel reference
-		for (int i = 0; i < referencelist.size(); i++) {
-			IReference ref = referencelist.get(i);
-			List<IKey> refKeys = ref.getKeys();
-
-			// assert the submodel id
-			assertEquals(submodelids[i], refKeys.get(0).getValue());
-			// assert the id type
-			assertEquals("IRI", refKeys.get(0).getIdType().name());
-			// assert the model type
-			assertEquals("SUBMODEL", refKeys.get(0).getType().name());
-			// submodels are local
-			assertEquals(true, refKeys.get(0).isLocal());
-		}
-
-	}
-
-	/**
-	 * Check parsed submodels with expected ones
-	 * 
-	 * @param submodels
-	 */
-	private void checkSubmodels(Set<ISubModel> submodels) {
-		assertEquals(5, submodels.size());
-
-		// filter the submodel with id "Nameplate"
-		Optional<ISubModel> sm1Optional = submodels.stream().filter(s -> s.getIdShort().equals("Nameplate")).findFirst();
-		assertTrue(sm1Optional.isPresent());
-		ISubModel sm1 = sm1Optional.get();
-
-		// verify short id, id-type, id and model-kind of the submodel
-		assertEquals("Nameplate", sm1.getIdShort());
-		assertEquals("IRI", sm1.getIdentification().getIdType().name());
-		assertEquals("www.company.com/ids/sm/4343_5072_7091_3242", sm1.getIdentification().getId());
-		assertEquals("Instance", sm1.getModelingKind().toString());
-
-		// ---------------------------------------------
-		// get 1st submodel element
-		// Get submodel elements
-		Map<String, ISubmodelElement> smElements = sm1.getSubmodelElements();
-
-		// get element manufacturing name
-		ISubmodelElement sele = smElements.get("ManufacturerName");
-
-		// verify short id
-		assertEquals("ManufacturerName", sele.getIdShort());
-
-		// verify category and model-kind, value and value-type
-		assertEquals("PARAMETER", sele.getCategory());
-		assertTrue(sele.getModelingKind().name().equalsIgnoreCase("Instance"));
-		Property prop = (Property) sele;
-		assertEquals("Festo AG & Co. KG", prop.get());
-		assertEquals("string", prop.getValueType());
-
-		// get semantic id
-		IReference semantic = sele.getSemanticId();
-
-		IKey semanticKey = semantic.getKeys().get(0);
-		assertTrue(semanticKey.getType().name().equalsIgnoreCase("ConceptDescription"));
-		assertEquals("IRDI", semanticKey.getIdType().name());
-		assertEquals("0173-1#02-AAO677#002", semanticKey.getValue());
-		assertEquals(true, semanticKey.isLocal());
-
-		/// ---------------------------------------------
-		// get 2nd submodel element
-		// Get submodel elements
-		sele = smElements.get("ManufacturerProductDesignation");
-		assertEquals("ManufacturerProductDesignation", sele.getIdShort());
-		assertEquals("PARAMETER", sele.getCategory());
-		assertTrue(sele.getModelingKind().name().equalsIgnoreCase("Instance"));
-		prop = (Property) sele;
-		assertEquals("OVEL Vacuum generator", prop.get());
-		assertEquals("string", prop.getValueType());
-
-		// get semantic id
-		semantic = sele.getSemanticId();
-		semanticKey = semantic.getKeys().get(0);
-		assertTrue(semanticKey.getType().name().equalsIgnoreCase("ConceptDescription"));
-		assertEquals("IRDI", semanticKey.getIdType().name());
-		assertEquals("0173-1#02-AAW338#001", semanticKey.getValue());
-		assertEquals(true, semanticKey.isLocal());
-
-		// ---------------------------------------------
-		// get 3rd submodel element
-		// Get submodel elements
-		sele = smElements.get("PhysicalAddress");
-		assertEquals("PhysicalAddress", sele.getIdShort());
-		assertEquals("PARAMETER", sele.getCategory());
-		assertTrue(sele.getModelingKind().name().equalsIgnoreCase("Instance"));
-
-		// get semantic id
-		semantic = sele.getSemanticId();
-		semanticKey = semantic.getKeys().get(0);
-		assertTrue(semanticKey.getType().name().equalsIgnoreCase("ConceptDescription"));
-		assertEquals("IRI", semanticKey.getIdType().name());
-		assertEquals("https://www.hsu-hh.de/aut/aas/physicaladdress", semanticKey.getValue());
-		assertEquals(true, semanticKey.isLocal());
-
-		// get values
-		assertTrue(sele.getModelType().equalsIgnoreCase("SubmodelElementCollection"));
-		SubmodelElementCollection collection = (SubmodelElementCollection) sele;
-		Collection<ISubmodelElement> subelements = collection.getValue();
-
-		assertEquals(5, subelements.size());
-		Iterator<ISubmodelElement> iterator = subelements.iterator();
-		Property prop1 = (Property) (iterator.next());
-		assertEquals("CountryCode", prop1.getIdShort());
-		assertEquals("DE", prop1.get());
-
-		Property prop2 = (Property) (iterator.next());
-		assertEquals("Street", prop2.getIdShort());
-		assertEquals("Ruiter Straße 82", prop2.get());
-	}
-
-}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.AASX/src/test/resources/.env b/components/basys.components/basyx.components.docker/basyx.components.AASX/src/test/resources/.env
deleted file mode 100644
index 0eea4b9..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.AASX/src/test/resources/.env
+++ /dev/null
@@ -1,5 +0,0 @@
-BASYX_HOST_PORT=8082
-BASYX_CONTAINER_PORT=4000
-BASYX_IMAGE_NAME=basys/aasx
-BASYX_CONTAINER_NAME=aasx
-BASYX_IMAGE_TAG=0.0.1-SNAPSHOT
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.registry/Dockerfile b/components/basys.components/basyx.components.docker/basyx.components.registry/Dockerfile
new file mode 100644
index 0000000..c9f4b78
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/Dockerfile
@@ -0,0 +1,34 @@
+# Add java runtime environment for execution
+FROM java:8-jdk-alpine 
+
+# Copy built jar to image using the jar name specified in the pom.xml (JAR_FILE)
+ARG JAR_FILE
+COPY target/${JAR_FILE} /usr/share/basyxExecutable.jar
+COPY target/lib /usr/share/lib
+COPY src/main/resources/context.properties /usr/share/config/context.properties
+COPY src/main/resources/registry.properties /usr/share/config/registry.properties
+COPY src/test/resources/dockerSQL.properties /usr/share/config/sql.properties
+COPY src/test/resources/dockerMongodb.properties /usr/share/config/mongodb.properties
+ 
+# Expose the appropriate port. In case of Tomcat, this is 8080.
+ARG PORT
+EXPOSE ${PORT} 
+
+# Set the path for the registry configuration file
+ARG REGISTRY_CONFIG_KEY
+ENV ${REGISTRY_CONFIG_KEY} "/usr/share/config/registry.properties"
+
+# Set the path for the context configuration file
+ARG CONTEXT_CONFIG_KEY
+ENV ${CONTEXT_CONFIG_KEY} "/usr/share/config/context.properties"
+
+# Set the path for the sql configuration file
+ARG SQL_CONFIG_KEY
+ENV ${SQL_CONFIG_KEY} "/usr/share/config/sql.properties"
+
+# Set the path for the mongodb configuration file
+ARG MONGODB_CONFIG_KEY
+ENV ${MONGODB_CONFIG_KEY} "/usr/share/config/mongodb.properties"
+
+# Start the jar
+CMD java -jar "/usr/share/basyxExecutable.jar"
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.registry/build.bat b/components/basys.components/basyx.components.docker/basyx.components.registry/build.bat
new file mode 100644
index 0000000..64f74e3
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/build.bat
@@ -0,0 +1 @@
+../.././mvnw clean install -U -Pdocker -DskipTests
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.registry/build.sh b/components/basys.components/basyx.components.docker/basyx.components.registry/build.sh
new file mode 100644
index 0000000..6820ccc
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/build.sh
@@ -0,0 +1,2 @@
+#!/usr/bin/env sh
+../../mvnw clean install -U -Pdocker -DskipTests
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.registry/docker-compose.yml b/components/basys.components/basyx.components.docker/basyx.components.registry/docker-compose.yml
new file mode 100644
index 0000000..717a3e3
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/docker-compose.yml
@@ -0,0 +1,25 @@
+version: '2.1'
+services:
+  registry:
+    image: ${BASYX_IMAGE_NAME}:${BASYX_IMAGE_TAG}
+    container_name: ${BASYX_CONTAINER_NAME}
+    ports:
+      - ${BASYX_HOST_PORT}:${BASYX_CONTAINER_PORT}
+#    depends_on:
+#      mongodb:
+#        condition: service_healthy
+#    links:
+#      - mongodb
+
+#  mongodb:
+#    image: mongo:latest
+#    container_name: mongodb
+# Possibility to enable authentication
+#    environment:
+#      MONGO_INITDB_ROOT_USERNAME: root
+#      MONGO_INITDB_ROOT_PASSWORD: example
+#    healthcheck:
+#      test: echo 'db.runCommand("ping").ok' | mongo mongodb:27017/test --quiet
+#      interval: 3s
+#      timeout: 3s
+#      retries: 5
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.registry/pom.xml b/components/basys.components/basyx.components.docker/basyx.components.registry/pom.xml
new file mode 100644
index 0000000..0185e3f
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/pom.xml
@@ -0,0 +1,95 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+
+	<parent>
+		<groupId>org.eclipse.basyx</groupId>
+		<artifactId>basyx.components.docker</artifactId>
+		<version>1.0.0</version>
+    </parent>
+	
+	<artifactId>basyx.components.registry</artifactId>
+	<name>BaSyx Registry</name>
+	<version>1.0.2</version>
+	
+	<properties>
+		<basyx.components.executable>org.eclipse.basyx.components.registry.executable.RegistryExecutable</basyx.components.executable>
+	</properties>
+	
+	<packaging>jar</packaging>
+	
+	<build>
+		<!-- Define additional plugins that are not included by default -->
+		<!-- Plugin configuration is done in parent project(s) -->
+		<plugins>
+			<!-- Attach sources to jar file -->
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-source-plugin</artifactId>
+			</plugin>
+		</plugins>
+	</build>
+	
+	<dependencies>
+		<!-- Use MongoDB Java Drivers for db connections -->
+	    <dependency>
+	        <groupId>org.mongodb</groupId>
+	        <artifactId>mongodb-driver-sync</artifactId>
+	        <version>4.0.5</version>
+	    </dependency>
+
+		<!-- Use Spring Data MongoDB for db data management -->		
+		<dependency>
+			<groupId>org.springframework.data</groupId>
+			<artifactId>spring-data-mongodb</artifactId>
+			<version>3.0.2.RELEASE</version>
+		</dependency>
+	
+		<!-- Adds additional classes of the BaSys SDK for tests (for TestRegistryProvider) -->
+		<dependency>
+			<groupId>org.eclipse.basyx</groupId>
+			<artifactId>basyx.sdk</artifactId>
+			<classifier>tests</classifier>
+		</dependency>
+	</dependencies>
+	
+	<profiles>
+		<profile>
+			<id>docker</id>
+			<build>
+				<plugins>
+					<!-- Read maven properties from file -->
+					<plugin>
+						<groupId>org.codehaus.mojo</groupId>
+						<artifactId>properties-maven-plugin</artifactId>
+					</plugin>
+				
+					<!-- Copy the dependencies necessary to run the jar -->
+					<plugin>
+						<groupId>org.apache.maven.plugins</groupId>
+						<artifactId>maven-dependency-plugin</artifactId>
+					</plugin>
+				
+					<!-- Build the docker image -->
+					<plugin>
+						<groupId>com.spotify</groupId>
+						<artifactId>dockerfile-maven-plugin</artifactId>
+					</plugin>
+				
+					<!-- Create integration test environment -->
+					<plugin>
+						<groupId>com.dkanejs.maven.plugins</groupId>
+						<artifactId>docker-compose-maven-plugin</artifactId>
+					</plugin>
+					
+					<!-- Run integration tests -->
+					<plugin>    
+						<groupId>org.apache.maven.plugins</groupId>
+						<artifactId>maven-failsafe-plugin</artifactId>
+					</plugin>
+				</plugins>
+			</build>
+		</profile>
+	</profiles>
+</project>
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/RegistryComponent.java b/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/RegistryComponent.java
new file mode 100644
index 0000000..1070cd9
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/RegistryComponent.java
@@ -0,0 +1,190 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.components.registry;
+
+import javax.servlet.http.HttpServlet;
+
+import org.eclipse.basyx.components.IComponent;
+import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
+import org.eclipse.basyx.components.configuration.BaSyxMongoDBConfiguration;
+import org.eclipse.basyx.components.configuration.BaSyxSQLConfiguration;
+import org.eclipse.basyx.components.registry.configuration.BaSyxRegistryConfiguration;
+import org.eclipse.basyx.components.registry.configuration.RegistryBackend;
+import org.eclipse.basyx.components.registry.servlet.InMemoryRegistryServlet;
+import org.eclipse.basyx.components.registry.servlet.MongoDBRegistryServlet;
+import org.eclipse.basyx.components.registry.servlet.SQLRegistryServlet;
+import org.eclipse.basyx.vab.protocol.http.server.BaSyxHTTPServer;
+import org.eclipse.basyx.vab.protocol.http.server.BaSyxContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Generic registry that can start and stop a registry with different kinds of backends.
+ * Currently supports MongoDB and SQL. For development purposes, the component can also start a
+ * registry without a backend and without persistency.
+ * 
+ * @author espen
+ *
+ */
+public class RegistryComponent implements IComponent {
+	private static Logger logger = LoggerFactory.getLogger(RegistryComponent.class);
+	
+	// The server with the servlet that will be created
+	private BaSyxHTTPServer server;
+
+	// The component configuration
+	private BaSyxContextConfiguration contextConfig;
+	private BaSyxRegistryConfiguration registryConfig;
+
+	// The backend configuration
+	private BaSyxMongoDBConfiguration mongoDBConfig;
+	private BaSyxSQLConfiguration sqlConfig;
+
+	/**
+	 * Default constructor that loads default configurations
+	 */
+	public RegistryComponent() {
+		contextConfig = new BaSyxContextConfiguration();
+		registryConfig = new BaSyxRegistryConfiguration();
+	}
+
+	/**
+	 * Constructor with given configuration for the registry and its server context. This constructor will create an
+	 * InMemory registry.
+	 * 
+	 * @param contextConfig The context configuration
+	 */
+	public RegistryComponent(BaSyxContextConfiguration contextConfig) {
+		this.contextConfig = contextConfig;
+		this.registryConfig = new BaSyxRegistryConfiguration(RegistryBackend.INMEMORY);
+	}
+
+	/**
+	 * Constructor with given configuration for the registry and its server context. This constructor will create a
+	 * registry with a MongoDB backend.
+	 * 
+	 * @param contextConfig The context configuration
+	 * @param mongoDBConfig The mongoDB configuration
+	 */
+	public RegistryComponent(BaSyxContextConfiguration contextConfig, BaSyxMongoDBConfiguration mongoDBConfig) {
+		this.contextConfig = contextConfig;
+		this.registryConfig = new BaSyxRegistryConfiguration(RegistryBackend.MONGODB);
+		this.mongoDBConfig = mongoDBConfig;
+	}
+
+	/**
+	 * Constructor with given configuration for the registry and its server context. This constructor will create a
+	 * registry with an SQL backend.
+	 * 
+	 * @param contextConfig The context configuration
+	 * @param sqlConfig     The sql configuration
+	 */
+	public RegistryComponent(BaSyxContextConfiguration contextConfig, BaSyxSQLConfiguration sqlConfig) {
+		this.contextConfig = contextConfig;
+		this.registryConfig = new BaSyxRegistryConfiguration(RegistryBackend.SQL);
+		this.sqlConfig = sqlConfig;
+	}
+
+	/**
+	 * Constructor with given configuration for the registry and its server context.
+	 * Will load the backend configuration using the default load process.
+	 * 
+	 * @param contextConfig  The context configuration
+	 * @param registryConfig The registry configuration
+	 */
+	public RegistryComponent(BaSyxContextConfiguration contextConfig, BaSyxRegistryConfiguration registryConfig) {
+		this.contextConfig = contextConfig;
+		this.registryConfig = registryConfig;
+	}
+
+	/**
+	 * Starts the context at http://${hostName}:${port}/${path}
+	 */
+	@Override
+	public void startComponent() {
+		BaSyxContext context = contextConfig.createBaSyxContext();
+		context.addServletMapping("/*", loadRegistryServlet());
+		server = new BaSyxHTTPServer(context);
+		server.start();
+		logger.info("Registry server started");
+	}
+
+	/**
+	 * Loads a registry with a backend according to the registryConfig
+	 * 
+	 * @return
+	 */
+	private HttpServlet loadRegistryServlet() {
+		HttpServlet registryServlet = null;
+		RegistryBackend backendType = registryConfig.getRegistryBackend();
+		switch(backendType) {
+			case MONGODB:
+				registryServlet = loadMongoDBRegistryServlet();
+				break;
+			case SQL:
+				registryServlet = loadSQLRegistryServlet();
+				break;
+			case INMEMORY:
+				registryServlet = loadInMemoryRegistryServlet();
+				break;
+		}
+		return registryServlet;
+	}
+
+	/**
+	 * Creates a registry servlet with an sql backend
+	 * 
+	 * @return
+	 */
+	private HttpServlet loadSQLRegistryServlet() {
+		logger.info("Loading SQLRegistry");
+		BaSyxSQLConfiguration config;
+		if (this.sqlConfig == null) {
+			config = new BaSyxSQLConfiguration();
+			config.loadFromDefaultSource();
+		} else {
+			config = this.sqlConfig;
+		}
+		return new SQLRegistryServlet(config);
+	}
+
+	/**
+	 * Creates a registry servlet with an mongodb backend
+	 * 
+	 * @return
+	 */
+	private HttpServlet loadMongoDBRegistryServlet() {
+		logger.info("Loading MongoDBRegistry");
+		BaSyxMongoDBConfiguration config;
+		if (this.mongoDBConfig == null) {
+			config = new BaSyxMongoDBConfiguration();
+			config.loadFromDefaultSource();
+		} else {
+			config = this.mongoDBConfig;
+		}
+		return new MongoDBRegistryServlet(config);
+	}
+
+	/**
+	 * Creates an registry servlet with in memory data (=> not persistent)
+	 * 
+	 * @return
+	 */
+	private HttpServlet loadInMemoryRegistryServlet() {
+		logger.info("Loading InMemoryRegistry");
+		return new InMemoryRegistryServlet();
+	}
+
+	@Override
+	public void stopComponent() {
+		server.shutdown();
+		logger.info("Registry server stopped");
+	}
+}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/configuration/BaSyxRegistryConfiguration.java b/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/configuration/BaSyxRegistryConfiguration.java
new file mode 100644
index 0000000..418daaa
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/configuration/BaSyxRegistryConfiguration.java
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.components.registry.configuration;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.basyx.components.configuration.BaSyxConfiguration;
+
+/**
+ * Represents a BaSyx registry configuration for a BaSyx Registry with any backend,
+ * that can be loaded from a properties file.
+ * 
+ * @author espen
+ *
+ */
+public class BaSyxRegistryConfiguration extends BaSyxConfiguration {
+	// Prefix for environment variables
+	public static final String ENV_PREFIX = "BaSyxRegistry_";
+
+	// Default BaSyx Context configuration
+	public static final String DEFAULT_BACKEND = RegistryBackend.INMEMORY.toString();
+
+	// Configuration keys
+	public static final String BACKEND = "registry.backend";
+
+	// The default path for the context properties file
+	public static final String DEFAULT_CONFIG_PATH = "registry.properties";
+
+	// The default key for variables pointing to the configuration file
+	public static final String DEFAULT_FILE_KEY = "BASYX_REGISTRY";
+
+	public static Map<String, String> getDefaultProperties() {
+		Map<String, String> defaultProps = new HashMap<>();
+		defaultProps.put(BACKEND, DEFAULT_BACKEND);
+		return defaultProps;
+	}
+
+	public BaSyxRegistryConfiguration() {
+		super(getDefaultProperties());
+	}
+
+	public BaSyxRegistryConfiguration(RegistryBackend backend) {
+		super(getDefaultProperties());
+		setRegistryBackend(backend);
+	}
+
+	public BaSyxRegistryConfiguration(Map<String, String> values) {
+		super(values);
+	}
+
+	public void loadFromEnvironmentVariables() {
+		loadFromEnvironmentVariables(ENV_PREFIX, BACKEND);
+	}
+
+	public void loadFromDefaultSource() {
+		loadFileOrDefaultResource(DEFAULT_FILE_KEY, DEFAULT_CONFIG_PATH);
+		loadFromEnvironmentVariables();
+	}
+
+	public RegistryBackend getRegistryBackend() {
+		return RegistryBackend.fromString(getProperty(BACKEND));
+	}
+
+	public void setRegistryBackend(RegistryBackend backend) {
+		setProperty(BACKEND, backend.toString());
+	}
+}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/configuration/RegistryBackend.java b/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/configuration/RegistryBackend.java
new file mode 100644
index 0000000..cec5be6
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/configuration/RegistryBackend.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.components.registry.configuration;
+
+import org.eclipse.basyx.submodel.metamodel.enumhelper.StandardizedLiteralEnumHelper;
+
+import com.google.common.base.Strings;
+
+/**
+ * Possible types for registry backends.
+ * 
+ * @author espen
+ *
+ */
+public enum RegistryBackend {
+	/**
+	 * Enum values of KeyElements
+	 */
+	INMEMORY("InMemory"),
+	SQL("SQL"),
+	MONGODB("MongoDB");
+	
+	private String literal;
+
+	private RegistryBackend(String literal) {
+		this.literal = literal;
+	}
+
+	@Override
+	public String toString() {
+		return literal;
+	}
+
+	/**
+	 * Method to transform string literal to RegistryBackend enum.
+	 * 
+	 * @see StandardizedLiteralEnumHelper StandardizedLiteralEnumHelper
+	 * 
+	 * @param literal
+	 * @return
+	 */
+	public static RegistryBackend fromString(String literal) {
+		if (Strings.isNullOrEmpty(literal)) {
+			return null;
+		}
+
+		RegistryBackend[] enumConstants = RegistryBackend.class.getEnumConstants();
+		for (RegistryBackend constant : enumConstants) {
+			if (constant.toString().equals(literal)) {
+				return constant;
+			}
+		}
+		throw new IllegalArgumentException("The literal '" + literal + "' is not a valid RegistryBackend");
+	}
+}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/executable/RegistryExecutable.java b/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/executable/RegistryExecutable.java
new file mode 100644
index 0000000..57e6dec
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/executable/RegistryExecutable.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.components.registry.executable;
+
+import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
+import org.eclipse.basyx.components.registry.RegistryComponent;
+import org.eclipse.basyx.components.registry.configuration.BaSyxRegistryConfiguration;
+
+/**
+ * A registry executable for a registry with any backend.
+ * 
+ * @author espen
+ */
+public class RegistryExecutable {
+	private RegistryExecutable() {
+	}
+
+	public static void main(String[] args) {
+		// Load context configuration from default source
+		BaSyxContextConfiguration contextConfig = new BaSyxContextConfiguration();
+		contextConfig.loadFromDefaultSource();
+
+		// Load registry configuration from default source
+		BaSyxRegistryConfiguration registryConfig = new BaSyxRegistryConfiguration();
+		registryConfig.loadFromDefaultSource();
+
+		// Create and start component according to the configuration
+		RegistryComponent component = new RegistryComponent(contextConfig, registryConfig);
+		component.startComponent();
+	}
+}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/mongodb/MongoDBRegistryHandler.java b/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/mongodb/MongoDBRegistryHandler.java
new file mode 100644
index 0000000..acb080e
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/mongodb/MongoDBRegistryHandler.java
@@ -0,0 +1,127 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.components.registry.mongodb;
+
+import static org.springframework.data.mongodb.core.query.Criteria.where;
+import static org.springframework.data.mongodb.core.query.Query.query;
+
+import java.util.List;
+
+import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
+import org.eclipse.basyx.aas.registration.memory.IRegistryHandler;
+import org.eclipse.basyx.components.configuration.BaSyxMongoDBConfiguration;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Identifiable;
+import org.springframework.data.mongodb.core.MongoOperations;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.data.mongodb.core.query.Criteria;
+
+import com.mongodb.client.MongoClient;
+import com.mongodb.client.MongoClients;
+
+/**
+ * A registry handler based on MongoDB
+ * 
+ * @author espen
+ */
+public class MongoDBRegistryHandler implements IRegistryHandler {
+	private static final String DEFAULT_CONFIG_PATH = "mongodb.properties";
+
+	protected BaSyxMongoDBConfiguration config;
+	protected MongoOperations mongoOps;
+	protected String collection;
+
+	private static final String AASID = Identifiable.IDENTIFICATION + "." + Identifier.ID;
+	private static final String ASSETID = AASDescriptor.ASSET + "." + Identifiable.IDENTIFICATION + "." + Identifier.ID;
+
+	/**
+	 * Receives the path of the configuration.properties file in it's constructor.
+	 * 
+	 * @param configFilePath
+	 */
+	public MongoDBRegistryHandler(BaSyxMongoDBConfiguration config) {
+		this.setConfiguration(config);
+	}
+
+	/**
+	 * Receives the path of the .properties file in it's constructor from a resource.
+	 */
+	public MongoDBRegistryHandler(String resourceConfigPath) {
+		config = new BaSyxMongoDBConfiguration();
+		config.loadFromResource(resourceConfigPath);
+		this.setConfiguration(config);
+	}
+
+	/**
+	 * Constructor using default sql connections
+	 */
+	public MongoDBRegistryHandler() {
+		this(DEFAULT_CONFIG_PATH);
+	}
+
+	public void setConfiguration(BaSyxMongoDBConfiguration config) {
+		this.config = config;
+		MongoClient client = MongoClients.create(config.getConnectionUrl());
+		this.mongoOps = new MongoTemplate(client, config.getDatabase());
+		this.collection = config.getRegistryCollection();
+	}
+
+	@Override
+	public boolean contains(IIdentifier identifier) {
+		String id = identifier.getId();
+		Criteria hasId = new Criteria();
+		hasId.orOperator(where(AASID).is(id), where(ASSETID).is(id));
+		return mongoOps.exists(query(hasId), collection);
+	}
+
+	@Override
+	public void remove(IIdentifier identifier) {
+		String id = identifier.getId();
+		Criteria hasId = new Criteria();
+		hasId.orOperator(where(AASID).is(id), where(ASSETID).is(id));
+		mongoOps.remove(query(hasId), collection);
+	}
+
+	@Override
+	public void insert(AASDescriptor descriptor) {
+		mongoOps.insert(descriptor, collection);
+	}
+
+	@Override
+	public void update(AASDescriptor descriptor) {
+		String aasId = descriptor.getIdentifier().getId();
+		Object result = mongoOps.findAndReplace(query(where(AASID).is(aasId)), descriptor, collection);
+		if (result == null) {
+			insert(descriptor);
+		}
+	}
+
+	@Override
+	public AASDescriptor get(IIdentifier identifier) {
+		String id = identifier.getId();
+		Criteria hasId = new Criteria();
+		hasId.orOperator(where(AASID).is(id), where(ASSETID).is(id));
+		AASDescriptor result = mongoOps.findOne(query(hasId), AASDescriptor.class, collection);
+		if (result != null) {
+			// Remove mongoDB-specific map attribute from AASDescriptor
+			result.remove("_id");
+		}
+		return result;
+	}
+
+	@Override
+	public List<AASDescriptor> getAll() {
+		List<AASDescriptor> result = mongoOps.findAll(AASDescriptor.class, collection);
+		// Remove mongoDB-specific map attribute from AASDescriptor
+		result.forEach(desc -> desc.remove("_id"));
+		return result;
+	}
+}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/servlet/InMemoryRegistryServlet.java b/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/servlet/InMemoryRegistryServlet.java
new file mode 100644
index 0000000..6a040fa
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/servlet/InMemoryRegistryServlet.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.components.registry.servlet;
+
+import org.eclipse.basyx.aas.registration.memory.InMemoryRegistry;
+import org.eclipse.basyx.aas.registration.restapi.AASRegistryModelProvider;
+import org.eclipse.basyx.vab.protocol.http.server.VABHTTPInterface;
+
+/**
+ * A registry servlet based on an InMemory Registry. The servlet therefore provides an implementation
+ * for the IAASRegistryService interface without a permanent storage capability.
+ * 
+ * Do not use this registry in a productive environment - the entries are not persistent!
+ * 
+ * @author espen
+ */
+public class InMemoryRegistryServlet extends VABHTTPInterface<AASRegistryModelProvider> {
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * Constructor with ModelProvider based on an InMemoryRegistry
+	 */
+	public InMemoryRegistryServlet() {
+		super(new AASRegistryModelProvider(new InMemoryRegistry()));
+
+	}
+}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/servlet/MongoDBRegistryServlet.java b/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/servlet/MongoDBRegistryServlet.java
new file mode 100644
index 0000000..73cff45
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/servlet/MongoDBRegistryServlet.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.components.registry.servlet;
+
+import org.eclipse.basyx.aas.registration.memory.AASRegistry;
+import org.eclipse.basyx.aas.registration.restapi.AASRegistryModelProvider;
+import org.eclipse.basyx.components.configuration.BaSyxMongoDBConfiguration;
+import org.eclipse.basyx.components.registry.mongodb.MongoDBRegistryHandler;
+import org.eclipse.basyx.vab.protocol.http.server.VABHTTPInterface;
+
+/**
+ * A registry servlet based on an SQL database. The servlet therefore provides an implementation
+ * for the IAASRegistryService interface with a permanent storage solution.
+ * 
+ * @author espen
+ */
+public class MongoDBRegistryServlet extends VABHTTPInterface<AASRegistryModelProvider> {
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * Provide HTTP interface with JSONProvider to handle serialization and
+	 * SQLDirectoryProvider as backend
+	 */
+	public MongoDBRegistryServlet() {
+		super(new AASRegistryModelProvider(new AASRegistry(new MongoDBRegistryHandler())));
+	}
+
+	public MongoDBRegistryServlet(BaSyxMongoDBConfiguration config) {
+		super(new AASRegistryModelProvider(new AASRegistry(new MongoDBRegistryHandler(config))));
+	}
+}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/servlet/SQLRegistryServlet.java b/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/servlet/SQLRegistryServlet.java
new file mode 100644
index 0000000..2033adf
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/servlet/SQLRegistryServlet.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.components.registry.servlet;
+
+import org.eclipse.basyx.aas.registration.restapi.AASRegistryModelProvider;
+import org.eclipse.basyx.components.configuration.BaSyxSQLConfiguration;
+import org.eclipse.basyx.components.registry.sql.SQLRegistry;
+import org.eclipse.basyx.vab.protocol.http.server.VABHTTPInterface;
+
+/**
+ * A registry servlet based on an SQL database. The servlet therefore provides an implementation
+ * for the IAASRegistryService interface with a permanent storage solution.
+ * 
+ * @author kuhn, pschorn, espen
+ */
+public class SQLRegistryServlet extends VABHTTPInterface<AASRegistryModelProvider> {
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * Provide HTTP interface with JSONProvider to handle serialization and
+	 * SQLDirectoryProvider as backend
+	 */
+	public SQLRegistryServlet() {
+		super(new AASRegistryModelProvider(new SQLRegistry()));
+	}
+
+	public SQLRegistryServlet(BaSyxSQLConfiguration sqlConfig) {
+		super(new AASRegistryModelProvider(new SQLRegistry(sqlConfig)));
+	}
+}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/sql/AASDescriptorMap.java b/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/sql/AASDescriptorMap.java
new file mode 100644
index 0000000..87cfc7e
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/sql/AASDescriptorMap.java
@@ -0,0 +1,138 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.components.registry.sql;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
+
+/**
+ * This is a map implementation for a <String, AASDescriptor> map which is needed
+ * by map registries. It is based on an arbitrary <String, Object> map and provides a proxy
+ * access to that map by assuming AASDescriptor entries.
+ * 
+ * @author espen
+ *
+ */
+public class AASDescriptorMap implements Map<String, AASDescriptor> {
+	/**
+	 * The map all operations of this map are based on
+	 */
+	private Map<String, Object> baseMap;
+
+	/**
+	 * Default constructor taking the base map
+	 * 
+	 * @param baseMap
+	 */
+	public AASDescriptorMap(Map<String, Object> baseMap) {
+		this.baseMap = baseMap;
+	}
+
+	@Override
+	public int size() {
+		return baseMap.size();
+	}
+
+	@Override
+	public boolean isEmpty() {
+		return baseMap.isEmpty();
+	}
+
+	@Override
+	public boolean containsKey(Object key) {
+		return baseMap.containsKey(key);
+	}
+
+	@Override
+	public boolean containsValue(Object value) {
+		return baseMap.containsValue(value);
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public AASDescriptor get(Object key) {
+		Map<String, Object> mapEntry = (Map<String, Object>) baseMap.get(key);
+		if (mapEntry == null) {
+			return null;
+		} else {
+			return new AASDescriptor(mapEntry);
+		}
+	}
+
+	@Override
+	public AASDescriptor put(String key, AASDescriptor value) {
+		return (AASDescriptor) baseMap.put(key, value);
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public AASDescriptor remove(Object key) {
+		Map<String, Object> result = (Map<String, Object>) baseMap.remove(key);
+		if (result == null) {
+			return null;
+		} else {
+			return new AASDescriptor(result);
+		}
+	}
+
+	@Override
+	public void putAll(Map<? extends String, ? extends AASDescriptor> m) {
+		baseMap.putAll(m);
+	}
+
+	@Override
+	public void clear() {
+		baseMap.clear();
+	}
+
+	@Override
+	public Set<String> keySet() {
+		return baseMap.keySet();
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public Collection<AASDescriptor> values() {
+		return baseMap.values().stream()
+				.map(o -> new AASDescriptor((Map<String, Object>) o))
+				.collect(Collectors.toList());
+	}
+
+	@Override
+	public Set<Entry<String, AASDescriptor>> entrySet() {
+		return baseMap.entrySet().stream()
+				.map(e -> new Entry<String, AASDescriptor>() {
+					@Override
+					public AASDescriptor setValue(AASDescriptor value) {
+						return (AASDescriptor) e.setValue(value);
+					}
+
+					@SuppressWarnings("unchecked")
+					@Override
+					public AASDescriptor getValue() {
+						if (e.getValue() == null) {
+							return null;
+						} else {
+							return new AASDescriptor((Map<String, Object>) e.getValue());
+						}
+					}
+
+					@Override
+					public String getKey() {
+						return e.getKey();
+					}
+				}).collect(Collectors.toSet());
+	}
+
+}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/sql/SQLRegistry.java b/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/sql/SQLRegistry.java
new file mode 100644
index 0000000..3b9733a
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/sql/SQLRegistry.java
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.components.registry.sql;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.Map;
+
+import javax.servlet.ServletException;
+
+import org.eclipse.basyx.aas.registration.memory.AASRegistry;
+import org.eclipse.basyx.aas.registration.memory.MapRegistryHandler;
+import org.eclipse.basyx.components.configuration.BaSyxSQLConfiguration;
+import org.eclipse.basyx.tools.sqlproxy.SQLRootElement;
+
+/**
+ * Implements a local registry based on an SQL database
+ * 
+ * @author espen
+ *
+ */
+public class SQLRegistry extends AASRegistry {
+	public final static String TABLE_ID = "root_registry";
+
+	/**
+	 * Constructor using default sql connection
+	 */
+	public SQLRegistry() {
+		super(new MapRegistryHandler(new AASDescriptorMap(createRootMap(new BaSyxSQLConfiguration()))));
+	}
+
+	/**
+	 * Creates a SQLRegistry from a sql configuration
+	 */
+	public SQLRegistry(BaSyxSQLConfiguration configuration) {
+		super(new MapRegistryHandler(new AASDescriptorMap(createRootMap(configuration))));
+	}
+
+	private static Map<String, Object> createRootMap(BaSyxSQLConfiguration config) {
+		SQLRootElement sqlRootElement = initSQLConnection(config);
+		sqlRootElement.createRootTableIfNotExists();
+		return sqlRootElement.retrieveRootMap();
+	}
+
+	/**
+	 * Initialize sqlDriver
+	 * 
+	 * @throws IOException
+	 * @throws FileNotFoundException
+	 * 
+	 * @throws ServletException
+	 */
+	private static final SQLRootElement initSQLConnection(BaSyxSQLConfiguration config) {
+		// SQL parameter
+		String path = config.getPath();
+		String user = config.getUser();
+		String pass = config.getPass();
+		String qryPfx = config.getPrefix();
+		String qDrvCls = config.getDriver();
+
+		// Create SQL driver instance
+		return new SQLRootElement(user, pass, path, qDrvCls, qryPfx, TABLE_ID);
+	}
+}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/resources/context.properties b/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/resources/context.properties
new file mode 100644
index 0000000..9ff1ad2
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/resources/context.properties
@@ -0,0 +1,24 @@
+# ###############################
+# HTTP Context configuration file
+# ###############################
+
+# ###############################
+# Context Path
+# ###############################
+# Specifies the subpath in the url for this server context
+ 
+contextPath=/registry
+
+# ###############################
+# Hostname
+# ###############################
+# Specifies the hostname for this server context
+
+contextHostname=localhost
+
+# ###############################
+# Port
+# ###############################
+# Specifies the port for this server context
+
+contextPort=4000
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/main/resources/logback.xml b/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/resources/logback.xml
similarity index 100%
rename from components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/main/resources/logback.xml
rename to components/basys.components/basyx.components.docker/basyx.components.registry/src/main/resources/logback.xml
diff --git a/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/resources/mongodb.properties b/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/resources/mongodb.properties
new file mode 100644
index 0000000..76dd4e4
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/resources/mongodb.properties
@@ -0,0 +1,32 @@
+# #############################
+# MongoDB Backend configuration
+# #############################
+
+# #############################
+# Database Name
+# #############################
+# The database in the MongoDB that hold the data
+
+dbname=admin
+
+# #############################
+# Connection String
+# #############################
+# MongoDB connection string for connecting to the MongoDB endpoint
+
+dbconnectionstring=mongodb://localhost:27017/
+
+# #############################
+# Registry Collections
+# #############################
+# Collection name that is used for storing registry data
+
+dbcollectionRegistry=registry
+
+# #############################
+# AAS collections
+# #############################
+# Collection names that are used for storing the AAS and Submodels
+
+# dbcollectionAAS=assetadministrationshells
+# dbcollectionSubmodels=submodels
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/resources/registry.properties b/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/resources/registry.properties
new file mode 100644
index 0000000..f0657a6
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/resources/registry.properties
@@ -0,0 +1,19 @@
+# ###########################
+# Registry configuration file
+# ###########################
+
+# ###########################
+# Backend
+# ###########################
+# Specifies the backend that loads the AAS and Submodels 
+
+# InMemory - does not persist AAS or submodels 
+registry.backend=InMemory
+
+# MongoDB - persists data within a MongoDB
+# See connection configuration in mongodb.properties
+# registry.backend=MongoDB
+
+# SQL - persists data within an SQL database
+# See connection configuration in sql.properties
+# registry.backend=SQL
diff --git a/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/resources/sql.properties b/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/resources/sql.properties
new file mode 100644
index 0000000..5199325
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/resources/sql.properties
@@ -0,0 +1,36 @@
+# ###############################
+# SQL database configuration file
+# ###############################
+
+# ###############################
+# Credentials
+# ###############################
+# Specifies the credentials for connecting to the SQL database 
+
+dbuser=postgres
+dbpass=admin
+
+# ###############################
+# Database URL
+# ###############################
+# The direct SQL database url for connection
+
+dburl=//localhost:5432/basyx-directory? 
+
+# ###############################
+# SQL driver information
+# ###############################
+# Java Driver and connection prefix for using the driver
+
+sqlDriver=org.postgresql.Driver
+sqlPrefix=jdbc:postgresql:
+
+
+# ###############################
+# Microsoft SQL Server Example
+# ###############################
+# dburl=//localhost:1234;databaseName=mydb
+# sqlDriver=com.microsoft.sqlserver.jdbc.SQLServerDriver
+# sqlPrefix=jdbc:sqlserver:
+
+
diff --git a/components/basys.components/basyx.components.docker/basyx.components.registry/src/test/java/org/eclipse/basyx/regression/registry/ITRegistry.java b/components/basys.components/basyx.components.docker/basyx.components.registry/src/test/java/org/eclipse/basyx/regression/registry/ITRegistry.java
new file mode 100644
index 0000000..ec16c95
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/src/test/java/org/eclipse/basyx/regression/registry/ITRegistry.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.regression.registry;
+
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
+import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
+import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
+import org.eclipse.basyx.components.configuration.BaSyxDockerConfiguration;
+import org.eclipse.basyx.testsuite.regression.aas.registration.TestRegistryProviderSuite;
+import org.junit.BeforeClass;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ITRegistry extends TestRegistryProviderSuite {
+	private static Logger logger = LoggerFactory.getLogger(ITRegistry.class);
+
+	private static String registryUrl;
+
+	@BeforeClass
+	public static void setUpClass() {
+		logger.info("Running integration test...");
+
+		logger.info("Loading servlet configuration");
+		// Load the servlet configuration inside of the docker configuration from properties file
+		BaSyxContextConfiguration contextConfig = new BaSyxContextConfiguration();
+		contextConfig.loadFromResource(BaSyxContextConfiguration.DEFAULT_CONFIG_PATH);
+
+		// Load the docker environment configuration from properties file
+		logger.info("Loading docker configuration");
+		BaSyxDockerConfiguration dockerConfig = new BaSyxDockerConfiguration();
+		dockerConfig.loadFromResource(BaSyxDockerConfiguration.DEFAULT_CONFIG_PATH);
+
+		registryUrl = "http://localhost:" + dockerConfig.getHostPort() + contextConfig.getContextPath();
+		logger.info("Registry URL for integration test: " + registryUrl);
+	}
+
+	@Override
+	protected IAASRegistry getRegistryService() {
+		return new AASRegistryProxy(registryUrl);
+	}
+}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.registry/src/test/java/org/eclipse/basyx/regression/registry/ITRegistryRaw.java b/components/basys.components/basyx.components.docker/basyx.components.registry/src/test/java/org/eclipse/basyx/regression/registry/ITRegistryRaw.java
new file mode 100644
index 0000000..354ca28
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/src/test/java/org/eclipse/basyx/regression/registry/ITRegistryRaw.java
@@ -0,0 +1,233 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.regression.registry;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.util.Collection;
+import java.util.Map;
+
+import javax.ws.rs.NotFoundException;
+
+import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
+import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
+import org.eclipse.basyx.components.configuration.BaSyxDockerConfiguration;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.tools.webserviceclient.WebServiceRawClient;
+import org.eclipse.basyx.vab.coder.json.metaprotocol.MetaprotocolHandler;
+import org.eclipse.basyx.vab.coder.json.serialization.DefaultTypeFactory;
+import org.eclipse.basyx.vab.coder.json.serialization.GSONTools;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Test raw http queries to SQL directory provider.
+ * 
+ * @author espen
+ *
+ */
+public class ITRegistryRaw {
+	private static Logger logger = LoggerFactory.getLogger(ITRegistryRaw.class);
+
+	/**
+	 * Serialization
+	 */
+	private static final GSONTools serializer = new GSONTools(new DefaultTypeFactory());
+	private static final MetaprotocolHandler handler = new MetaprotocolHandler();
+
+	/**
+	 * Invoke BaSyx service calls via web services
+	 */
+	private static final WebServiceRawClient client = new WebServiceRawClient();
+	private static String registryUrl;
+
+	/**
+	 * AASDescriptor to test
+	 */
+	private static final IIdentifier id1 = new ModelUrn("urn:de.FHG:es.iese:aas:0.98:5:lab:microscope#A-166");
+	private static final String endpoint1 = "www.endpoint.de";
+	private static final AASDescriptor aasDescriptor1 = new AASDescriptor(id1, endpoint1);
+	private static final String serializedDescriptor1 = serializer.serialize(aasDescriptor1);
+	private static final IIdentifier id2 = new ModelUrn("urn:de.FHG:es.iese:aas:0.98:5:lab:microscope#A-167");
+	private static final String endpoint2 = "www.endpoint2.de";
+	private static final String endpoint2b = "www.endpoint2.de";
+	private static final AASDescriptor aasDescriptor2 = new AASDescriptor(id2, endpoint2);
+	private static final AASDescriptor aasDescriptor2b = new AASDescriptor(id2, endpoint2b);
+	private static final String serializedDescriptor2 = serializer.serialize(aasDescriptor2);
+	private static final String serializedDescriptor2b = serializer.serialize(aasDescriptor2b);
+	private static final IIdentifier idUnknown = new ModelUrn("urn:de.FHG:es.iese:aas:0.98:5:lab:microscope#A-168");
+	private static String aasUrl1, aasUrl2, aasUrlUnknown;
+
+	@BeforeClass
+	public static void setUpClass() throws UnsupportedEncodingException {
+		logger.info("Running integration test...");
+
+		logger.info("Loading servlet configuration");
+		// Load the servlet configuration inside of the docker configuration from properties file
+		BaSyxContextConfiguration contextConfig = new BaSyxContextConfiguration();
+		contextConfig.loadFromResource(BaSyxContextConfiguration.DEFAULT_CONFIG_PATH);
+
+		// Load the docker environment configuration from properties file
+		logger.info("Loading docker configuration");
+		BaSyxDockerConfiguration dockerConfig = new BaSyxDockerConfiguration();
+		dockerConfig.loadFromResource(BaSyxDockerConfiguration.DEFAULT_CONFIG_PATH);
+
+		registryUrl = "http://localhost:" + dockerConfig.getHostPort() + contextConfig.getContextPath()
+				+ "/api/v1/registry/";
+		logger.info("Registry URL for integration test: " + registryUrl);
+		aasUrl1 = registryUrl + URLEncoder.encode(id1.getId(), "UTF-8");
+		aasUrl2 = registryUrl + URLEncoder.encode(id2.getId(), "UTF-8");
+		aasUrlUnknown = registryUrl + URLEncoder.encode(idUnknown.getId(), "UTF-8");
+
+		logger.info("Registry URL for integration test: " + registryUrl);
+	}
+
+	@Before
+	public void setUp() {
+		// Put serialized descriptor to register it
+		client.put(aasUrl1, serializedDescriptor1);
+		client.put(aasUrl2, serializedDescriptor2);
+	}
+
+	@After
+	public void tearDown() throws UnsupportedEncodingException {
+		// Delete AAS registration
+		try {
+			client.delete(aasUrl1);			
+		} catch(NotFoundException e) {}
+		try {
+			client.delete(aasUrl2);			
+		} catch(NotFoundException e) {}
+	}
+
+	/**
+	 * Execute test case that test working calls
+	 */
+	@SuppressWarnings("unchecked")
+	@Test
+	public void testGetterCalls() {
+		// First test - get all locally registered AAS
+		{
+			// Get all locally registered AAS
+			Collection<AASDescriptor> result = getResult(client.get(registryUrl));
+
+			// Check if all AAS are contained in result
+			assertEquals(2, result.size());
+		}
+
+		// Get a specific AAS (1)
+		try {
+			// Get a known AAS by its ID
+			AASDescriptor result = new AASDescriptor((Map<String, Object>) getResult(client.get(aasUrl1)));
+
+			// Check if all AAS are contained in result
+			assertEquals(id1.getId(), result.getIdentifier().getId());
+		} catch (Exception e) {
+			fail("Get specific AAS test case did throw exception:" + e);
+		}
+
+		// Get a specific AAS (2)
+		try {
+			// Get a known AAS by its ID
+			AASDescriptor result = new AASDescriptor((Map<String, Object>) getResult(client.get(aasUrl2)));
+
+			// Check if all AAS are contained in result
+			assertEquals(id2.getId(), result.getIdentifier().getId());
+		} catch (Exception e) {
+			fail("Get specific AAS test case did throw exception:" + e);
+		}
+	}
+
+	/**
+	 * Execute update test case
+	 * 
+	 * @throws UnsupportedEncodingException
+	 */
+	@SuppressWarnings("unchecked")
+	@Test
+	public void testUpdateCall() throws UnsupportedEncodingException {
+		// Update a specific AAS
+		// Update AAS registration
+		client.put(aasUrl2, serializedDescriptor2b);
+
+		// Get a known AAS by its ID
+		AASDescriptor result = new AASDescriptor((Map<String, Object>) getResult(client.get(aasUrl2)));
+		// - Check updated registration
+		assertEquals(endpoint2b, result.getFirstEndpoint());
+	}
+
+	/**
+	 * Execute create/Delete test cases
+	 * 
+	 * @throws UnsupportedEncodingException
+	 */
+	@SuppressWarnings("unchecked")
+	@Test
+	public void testCreateDeleteCall() throws UnsupportedEncodingException {
+		// Update a specific AAS
+		// Delete AAS registration (make sure tests work also if previous test suite
+		// did fail)
+		client.delete(aasUrl2);
+
+		// Try to get deleted AAS, has to throw exception
+		try {
+			getResult(client.get(aasUrl2));
+			fail();
+		} catch(NotFoundException e) {}
+
+		// Create new AAS registration
+		client.put(aasUrl2, serializedDescriptor2);
+
+		// Get a known AAS by its ID
+		AASDescriptor result2 = new AASDescriptor((Map<String, Object>) getResult(client.get(aasUrl2)));
+
+		assertEquals(endpoint2, result2.getFirstEndpoint()); // need deep json string compare here
+
+		// Delete AAS registration
+		client.delete(aasUrl2);
+
+		// Try to get deleted AAS, has to throw exception
+		try {
+			getResult(client.get(aasUrl2));
+			fail();
+		} catch(NotFoundException e) {}
+	}
+
+	/**
+	 * Execute test case that test non-working calls
+	 * 
+	 * @throws UnsupportedEncodingException
+	 */
+	@Test(expected = NotFoundException.class)
+	public void testNonWorkingCalls() throws UnsupportedEncodingException {
+		// Get unknown AAS ID, has to throw exception
+		getResult(client.get(aasUrlUnknown));
+		fail();
+	}
+
+	@SuppressWarnings("unchecked")
+	private <T> T getResult(String res) {
+		try {
+			return (T) handler.deserialize(res);
+		} catch (Exception e) {
+			e.printStackTrace();
+			throw new RuntimeException();
+		}
+	}
+
+}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.registry/src/test/java/org/eclipse/basyx/regression/registry/TestMongoDBRegistry.java b/components/basys.components/basyx.components.docker/basyx.components.registry/src/test/java/org/eclipse/basyx/regression/registry/TestMongoDBRegistry.java
new file mode 100644
index 0000000..93ef1d8
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/src/test/java/org/eclipse/basyx/regression/registry/TestMongoDBRegistry.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.regression.registry;
+
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
+import org.eclipse.basyx.aas.registration.memory.AASRegistry;
+import org.eclipse.basyx.components.registry.mongodb.MongoDBRegistryHandler;
+import org.eclipse.basyx.testsuite.regression.aas.registration.TestRegistryProviderSuite;
+
+/**
+ * Test class for a local registry provider based on SQL tables
+ * 
+ * @author espen
+ *
+ */
+public class TestMongoDBRegistry extends TestRegistryProviderSuite {
+
+	@Override
+	protected IAASRegistry getRegistryService() {
+		return new AASRegistry(new MongoDBRegistryHandler("mongodb.properties"));
+	}
+}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.registry/src/test/java/org/eclipse/basyx/regression/registry/TestSQLRegistryProvider.java b/components/basys.components/basyx.components.docker/basyx.components.registry/src/test/java/org/eclipse/basyx/regression/registry/TestSQLRegistryProvider.java
new file mode 100644
index 0000000..1541805
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/src/test/java/org/eclipse/basyx/regression/registry/TestSQLRegistryProvider.java
@@ -0,0 +1,85 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.regression.registry;
+
+import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
+import org.eclipse.basyx.components.configuration.BaSyxSQLConfiguration;
+import org.eclipse.basyx.components.registry.sql.SQLRegistry;
+import org.eclipse.basyx.testsuite.regression.aas.registration.TestRegistryProviderSuite;
+import org.eclipse.basyx.tools.sqlproxy.SQLRootElement;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * Test class for a local registry provider based on SQL tables
+ * 
+ * @author espen
+ *
+ */
+public class TestSQLRegistryProvider extends TestRegistryProviderSuite {
+
+	@BeforeClass
+	public static void setUpClass() {
+		SQLRootElement root = getSQLRootElement();
+		root.drop();
+	}
+
+	@AfterClass
+	public static void tearDownClass() {
+		SQLRootElement root = getSQLRootElement();
+		root.drop();
+	}
+
+	protected static SQLRootElement getSQLRootElement() {
+		// Load config
+		BaSyxSQLConfiguration config = new BaSyxSQLConfiguration();
+		config.loadFromResource("sql.properties");
+
+		// Create SQL driver instance
+		String path = config.getPath();
+		String user = config.getUser();
+		String pass = config.getPass();
+		String qryPfx = config.getPrefix();
+		String qDrvCls = config.getDriver();
+		return new SQLRootElement(user, pass, path, qDrvCls, qryPfx, SQLRegistry.TABLE_ID);
+	}
+
+	@Override
+	protected IAASRegistry getRegistryService() {
+		BaSyxSQLConfiguration sqlConfig = new BaSyxSQLConfiguration();
+		sqlConfig.loadFromResource("sql.properties");
+		return new SQLRegistry(sqlConfig);
+	}
+
+	/**
+	 * Tests, if the data has been persisted by creating a new registry with the same settings
+	 */
+	@Test
+	public void testPersistency() {
+		// Create new SQLRegistry with same configuration
+		BaSyxSQLConfiguration sqlConfig = new BaSyxSQLConfiguration();
+		sqlConfig.loadFromResource("sql.properties");
+		IAASRegistry registry = new SQLRegistry(sqlConfig);
+		
+		// Try to "overwrite" data
+		AASDescriptor aasDesc2 = new AASDescriptor(aasIdShort2, aasId2, asset2, aasEndpoint2);
+		proxy.register(aasDesc2);
+
+		// Retrieve and check the first AAS
+		AASDescriptor descriptor = registry.lookupAAS(aasId1);
+		super.validateDescriptor1(descriptor);
+
+		// Retrieve and check the second AAS
+		AASDescriptor descriptor2 = registry.lookupAAS(aasId2);
+		super.validateDescriptor2(descriptor2);
+	}
+}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.registry/src/test/resources/.env b/components/basys.components/basyx.components.docker/basyx.components.registry/src/test/resources/.env
new file mode 100644
index 0000000..36083e8
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/src/test/resources/.env
@@ -0,0 +1,39 @@
+# ##################
+# Docker Environment
+# ##################
+
+# ##################
+# Host Port
+# ##################
+# Specifies the port for the Docker HOST the container port is mapped to
+
+BASYX_HOST_PORT=8082
+
+# ##################
+# Container Port
+# ##################
+# Specifies the port for the Docker CONTAINER that is be mapped for the host 
+
+BASYX_CONTAINER_PORT=4000
+
+# ##################
+# Image Name
+# ##################
+# The image of the image that is build for this component
+
+BASYX_IMAGE_NAME=eclipsebasyx/aas-registry
+
+# ##################
+# Image Tag
+# ##################
+# The image tag of the image that is build for this component
+
+BASYX_IMAGE_TAG=1.0.2
+
+# ##################
+# Container Name
+# ##################
+# The name of the container used for the default environment
+ 
+BASYX_CONTAINER_NAME=registry
+
diff --git a/components/basys.components/basyx.components.docker/basyx.components.registry/src/test/resources/dockerMongodb.properties b/components/basys.components/basyx.components.docker/basyx.components.registry/src/test/resources/dockerMongodb.properties
new file mode 100644
index 0000000..e2caf5b
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/src/test/resources/dockerMongodb.properties
@@ -0,0 +1,34 @@
+# #############################
+# MongoDB Backend configuration
+# #############################
+
+# #############################
+# Database Name
+# #############################
+# The database in the MongoDB that hold the data
+
+dbname=admin
+
+# #############################
+# Connection String
+# #############################
+# MongoDB connection string for connecting to the MongoDB endpoint
+# Here it is not localhost, because the container has to address the mongodb
+# container in the default docker environment used in this component
+
+dbconnectionstring=mongodb://mongodb:27017/
+
+# #############################
+# Registry Collections
+# #############################
+# Collection name that is used for storing registry data
+
+dbcollectionRegistry=registry
+
+# #############################
+# AAS collections
+# #############################
+# Collection names that are used for storing the AAS and Submodels
+
+# dbcollectionAAS=assetadministrationshells
+# dbcollectionSubmodels=submodels
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.registry/src/test/resources/dockerSQL.properties b/components/basys.components/basyx.components.docker/basyx.components.registry/src/test/resources/dockerSQL.properties
new file mode 100644
index 0000000..3871d94
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/src/test/resources/dockerSQL.properties
@@ -0,0 +1,37 @@
+# ###############################
+# SQL database configuration file
+# ###############################
+
+# ###############################
+# Credentials
+# ###############################
+# Specifies the credentials for connecting to the SQL database 
+
+dbuser=postgres
+dbpass=admin
+
+# ###############################
+# Database URL
+# ###############################
+# The direct SQL database url for connection
+# Here it is not localhost, because the container has to address the postgreSQL
+# container in the default docker environment used in this component
+
+dburl=//postgres:5432/basyx-directory? 
+
+# ###############################
+# SQL driver information
+# ###############################
+# Java Driver and connection prefix for using the driver
+
+sqlDriver=org.postgresql.Driver
+sqlPrefix=jdbc:postgresql:
+
+
+# ###############################
+# Microsoft SQL Server Example
+# ###############################
+# dburl=//localhost:1234;databaseName=mydb
+# sqlDriver=com.microsoft.sqlserver.jdbc.SQLServerDriver
+# sqlPrefix=jdbc:sqlserver:
+
diff --git a/components/basys.components/basyx.components.docker/basyx.components.registry/start.bat b/components/basys.components/basyx.components.docker/basyx.components.registry/start.bat
new file mode 100644
index 0000000..f0ff9e1
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/start.bat
@@ -0,0 +1,3 @@
+cd src/test/resources
+docker-compose up
+cd ../../..
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.registry/start.sh b/components/basys.components/basyx.components.docker/basyx.components.registry/start.sh
new file mode 100644
index 0000000..4b9b54a
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/start.sh
@@ -0,0 +1,4 @@
+#!/usr/bin/env sh
+cd src/test/resources
+docker-compose up
+cd ../../..
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.registry/stop.bat b/components/basys.components/basyx.components.docker/basyx.components.registry/stop.bat
new file mode 100644
index 0000000..b645246
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/stop.bat
@@ -0,0 +1,3 @@
+cd src/test/resources
+docker-compose down
+cd ../../..
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.registry/stop.sh b/components/basys.components/basyx.components.docker/basyx.components.registry/stop.sh
new file mode 100644
index 0000000..e11a931
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/stop.sh
@@ -0,0 +1,4 @@
+#!/usr/bin/env sh
+cd src/test/resources
+docker-compose down
+cd ../../..
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.simple/Dockerfile b/components/basys.components/basyx.components.docker/basyx.components.simple/Dockerfile
deleted file mode 100644
index 3628774..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.simple/Dockerfile
+++ /dev/null
@@ -1,15 +0,0 @@
-# Add java runtime environment for execution
-FROM java:8-jdk-alpine 
-
-# Copy built jar to image using the jar name specified in the pom.xml (JAR_FILE)
-ARG JAR_FILE
-COPY target/${JAR_FILE} /usr/share/basyxExecutable.jar
-COPY target/lib /usr/share/lib
-COPY src/main/resources/context.properties /usr/share/context.properties
- 
-# Expose the appropriate port. In case of Tomcat, this is 8080.
-ARG PORT
-EXPOSE ${PORT}
- 
-# Start the jar
-CMD java -jar "/usr/share/basyxExecutable.jar" "/usr/share/context.properties"
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.simple/docker-compose.yml b/components/basys.components/basyx.components.docker/basyx.components.simple/docker-compose.yml
deleted file mode 100644
index aca4d1b..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.simple/docker-compose.yml
+++ /dev/null
@@ -1,31 +0,0 @@
-version: '3'
-services:
-
-  registry:
-    image: ${BASYX_IMAGE_NAME}:${BASYX_IMAGE_TAG}
-    container_name: ${BASYX_CONTAINER_NAME}
-    ports:
-      - ${BASYX_HOST_PORT}:${BASYX_CONTAINER_PORT}
-#    depends_on:
-#      - postgres
-#    volumes:
-#      -  .\WebContent\WEB-INF\config\directory\sqldirectory\directory.properties:/basys/directory.properties
-#    links:
-#      - postgres
-
-#  postgres:
-#    image: postgres:9.4
-#    container_name: postgres
-#    environment:
-#      - POSTGRES_USER:'postgres'
-#      - POSTGRES_PASSWORD:'admin'
-#      - POSTGRES_DB=basyx-directory
-#    volumes:
-#      - ./WebContent/WEB-INF/config/postgres/init.sql:/docker-entrypoint-initdb.d/init.sql
-#    ports:
-#      - 5433:5432
-#    expose:
-#      - 5432
-            
-
-      
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.simple/pom.xml b/components/basys.components/basyx.components.docker/basyx.components.simple/pom.xml
deleted file mode 100644
index 78b6354..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.simple/pom.xml
+++ /dev/null
@@ -1,95 +0,0 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-	<modelVersion>4.0.0</modelVersion>
-	
-	<!--
-		Simple Docker Component
-	 
-		Serves as a template for simple docker components that do not depend on other docker containers.
-		Do NOT use the included in-memory registry in a productive environment - the entries are not stored permanently
-	 -->
-
-	<parent>
-		<groupId>org.eclipse.basyx</groupId>
-		<artifactId>basyx.components.docker</artifactId>
-		<version>0.0.1-SNAPSHOT</version>
-    </parent>
-	
-	<artifactId>basyx.components.simple</artifactId>
-	<name>BaSyx Simple Docker Component</name>
-	
-	<properties>
-		<!--  
-			basyx.components.executable is the executable class with the definition of the public void main(String[]).
-			It is needed when building the jar in the maven-jar-plugin (see basyx.components.docker/pom.xml) 
-		-->
-		<basyx.components.executable>org.eclipse.basyx.components.executable.InMemoryRegistryExecutable</basyx.components.executable>
-	</properties>
-	
-	<packaging>jar</packaging>
-	
-	<!-- Define additional plugins that are not included by default -->
-	<!-- Plugin configuration is done in parent project(s) -->
-	<build>
-		<plugins>
-			<!-- Attach sources to jar file -->
-			<plugin>
-				<groupId>org.apache.maven.plugins</groupId>
-				<artifactId>maven-source-plugin</artifactId>
-			</plugin>
-		</plugins>
-	</build>
-	
-	<profiles>
-		<profile>
-			<!-- 
-				"Docker" profile - do not build & install docker images by default
-				Run "mvn install -Pdocker" in order to include docker  
-			-->
-			<id>docker</id>
-			<build>
-				<plugins>
-					<!-- Read maven properties from file -->
-					<plugin>
-						<groupId>org.codehaus.mojo</groupId>
-						<artifactId>properties-maven-plugin</artifactId>
-					</plugin>
-				
-					<!-- Copy the dependencies necessary to run the jar -->
-					<plugin>
-						<groupId>org.apache.maven.plugins</groupId>
-						<artifactId>maven-dependency-plugin</artifactId>
-					</plugin>
-				
-					<!-- Build the docker image -->
-					<plugin>
-						<groupId>com.spotify</groupId>
-						<artifactId>dockerfile-maven-plugin</artifactId>
-					</plugin>
-				
-					<!-- Create integration test environment -->
-					<plugin>
-						<groupId>com.dkanejs.maven.plugins</groupId>
-						<artifactId>docker-compose-maven-plugin</artifactId>
-					</plugin>
-					
-					<!-- Run integration tests -->
-					<plugin>    
-						<groupId>org.apache.maven.plugins</groupId>
-						<artifactId>maven-failsafe-plugin</artifactId>
-					</plugin>
-				</plugins>
-			</build>
-		</profile>
-	</profiles>
-	
-	<dependencies>
-		<!-- Adds additional classes of the BaSys SDK for tests (for TestRegistryProvider) -->
-		<dependency>
-			<groupId>org.eclipse.basyx</groupId>
-			<artifactId>basyx.sdk</artifactId>
-			<classifier>tests</classifier>
-		</dependency>
-	</dependencies>
-</project>
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.simple/src/main/java/org/eclipse/basyx/components/InMemoryRegistryComponent.java b/components/basys.components/basyx.components.docker/basyx.components.simple/src/main/java/org/eclipse/basyx/components/InMemoryRegistryComponent.java
deleted file mode 100644
index 972d21e..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.simple/src/main/java/org/eclipse/basyx/components/InMemoryRegistryComponent.java
+++ /dev/null
@@ -1,49 +0,0 @@
-package org.eclipse.basyx.components;
-
-import org.eclipse.basyx.components.servlets.InMemoryRegistryServlet;
-import org.eclipse.basyx.vab.protocol.http.server.AASHTTPServer;
-import org.eclipse.basyx.vab.protocol.http.server.BaSyxContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * A Registry component based on an InMemory Registry.
- * 
- * Do not use this registry in a productive environment - the entries are not persistent!
- * 
- * @author espen
- */
-public class InMemoryRegistryComponent {
-	private static Logger logger = LoggerFactory.getLogger(InMemoryRegistryComponent.class);
-
-	// BaSyx context information
-	private String hostName;
-	private int port;
-	private String path;
-	private String docBasePath;
-
-	// The server with the servlet that will be created
-	private AASHTTPServer server;
-
-	public InMemoryRegistryComponent(String hostName, int port, String path, String docBasePath) {
-		// Sets the server context
-		this.hostName = hostName;
-		this.port = port;
-		this.path = path;
-		this.docBasePath = docBasePath;
-	}
-
-	/**
-	 * Starts the InMemoryRegistry at http://${hostName}:${port}/${path}
-	 */
-	public void startComponent() {
-		logger.info("Create the server...");
-		// Init HTTP context and add an InMemoryRegistryServlet according to the configuration
-		BaSyxContext context = new BaSyxContext(path, docBasePath, hostName, port);
-		context.addServletMapping("/*", new InMemoryRegistryServlet());
-		server = new AASHTTPServer(context);
-
-		logger.info("Start the server...");
-		server.start();
-	}
-}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.simple/src/main/java/org/eclipse/basyx/components/executable/InMemoryRegistryExecutable.java b/components/basys.components/basyx.components.docker/basyx.components.simple/src/main/java/org/eclipse/basyx/components/executable/InMemoryRegistryExecutable.java
deleted file mode 100644
index eb7191d..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.simple/src/main/java/org/eclipse/basyx/components/executable/InMemoryRegistryExecutable.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package org.eclipse.basyx.components.executable;
-
-import org.eclipse.basyx.components.InMemoryRegistryComponent;
-import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * A registry servlet based on an InMemory Registry. The servlet therefore provides an implementation
- * for the IAASRegistryService interface without a permanent storage capability.
- * 
- * Do not use this registry in a productive environment - the entries are not persistent!
- * 
- * @author espen
- */
-public class InMemoryRegistryExecutable {
-	private static Logger logger = LoggerFactory.getLogger(InMemoryRegistryExecutable.class);
-
-	private InMemoryRegistryExecutable() {
-	}
-
-	public static void main(String[] args) {
-		logger.info("Starting BaSyx InMemory registry");
-
-		// Load configuration
-		BaSyxContextConfiguration config = new BaSyxContextConfiguration();
-		if (args.length > 0 && args[0] instanceof String) {
-			// file path available? => load configs from file
-			config.loadFromFile(args[0]);
-		} else {
-			// fallback: load default configs (in resources)
-			config.loadFromResource(BaSyxContextConfiguration.DEFAULT_CONFIG_PATH);
-		}
-
-		InMemoryRegistryComponent component = new InMemoryRegistryComponent(config.getHostname(), config.getPort(),
-				config.getContextPath(), config.getDocBasePath());
-		component.startComponent();
-	}
-}
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.simple/src/main/java/org/eclipse/basyx/components/servlets/InMemoryRegistryServlet.java b/components/basys.components/basyx.components.docker/basyx.components.simple/src/main/java/org/eclipse/basyx/components/servlets/InMemoryRegistryServlet.java
deleted file mode 100644
index 933577b..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.simple/src/main/java/org/eclipse/basyx/components/servlets/InMemoryRegistryServlet.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package org.eclipse.basyx.components.servlets;
-
-import org.eclipse.basyx.aas.registration.memory.InMemoryRegistry;
-import org.eclipse.basyx.aas.registration.restapi.DirectoryModelProvider;
-import org.eclipse.basyx.vab.protocol.http.server.VABHTTPInterface;
-
-/**
- * A registry servlet based on an InMemory Registry. The servlet therefore provides an implementation
- * for the IAASRegistryService interface without a permanent storage capability.
- * 
- * Do not use this registry in a productive environment - the entries are not persistent!
- * 
- * @author espen
- */
-public class InMemoryRegistryServlet extends VABHTTPInterface<DirectoryModelProvider> {
-	private static final long serialVersionUID = 1L;
-
-	/**
-	 * Constructor with ModelProvider based on an InMemoryRegistry
-	 */
-	public InMemoryRegistryServlet() {
-		super(new DirectoryModelProvider(new InMemoryRegistry()));
-
-	}
-}
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.simple/src/main/resources/context.properties b/components/basys.components/basyx.components.docker/basyx.components.simple/src/main/resources/context.properties
deleted file mode 100644
index 7e933a3..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.simple/src/main/resources/context.properties
+++ /dev/null
@@ -1,3 +0,0 @@
-contextPath=/registry
-contextHostname=localhost
-contextPort=4000
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.simple/src/main/resources/logback.xml b/components/basys.components/basyx.components.docker/basyx.components.simple/src/main/resources/logback.xml
deleted file mode 100644
index 86341d6..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.simple/src/main/resources/logback.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
- 
-<configuration>
- 
-  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
-    
-    <!-- Example for a filter, which removes all entries not containing "[TEST]" in the message. -->
-    
-    <!--<filter class="ch.qos.logback.core.filter.EvaluatorFilter">      
-      <evaluator>
-        <expression>return message.contains("[TEST]");</expression>
-      </evaluator>
-      <OnMismatch>DENY</OnMismatch>
-      <OnMatch>NEUTRAL</OnMatch>
-    </filter>-->
-  
-    <encoder>
-      <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{5} - %msg%n</pattern>
-    </encoder>
-  </appender>
-  
-  <root level="INFO">          
-    <appender-ref ref="STDOUT" />
-  </root>  
-   
-</configuration>
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.simple/src/test/java/org/eclipse/basyx/regression/docker/ITInMemoryRegistry.java b/components/basys.components/basyx.components.docker/basyx.components.simple/src/test/java/org/eclipse/basyx/regression/docker/ITInMemoryRegistry.java
deleted file mode 100644
index 0dbb7bf..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.simple/src/test/java/org/eclipse/basyx/regression/docker/ITInMemoryRegistry.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package org.eclipse.basyx.regression.docker;
-
-import org.eclipse.basyx.aas.registration.api.IAASRegistryService;
-import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
-import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
-import org.eclipse.basyx.components.configuration.BaSyxDockerConfiguration;
-import org.eclipse.basyx.testsuite.regression.aas.registration.TestRegistryProviderSuite;
-import org.junit.BeforeClass;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class ITInMemoryRegistry extends TestRegistryProviderSuite {
-	private static Logger logger = LoggerFactory.getLogger(ITInMemoryRegistry.class);
-
-	private static String registryUrl;
-
-	@BeforeClass
-	public static void setUpClass() {
-		logger.info("Running integration test...");
-
-		logger.info("Loading servlet configuration");
-		// Load the servlet configuration inside of the docker configuration from properties file
-		BaSyxContextConfiguration contextConfig = new BaSyxContextConfiguration();
-		contextConfig.loadFromResource(BaSyxContextConfiguration.DEFAULT_CONFIG_PATH);
-
-		// Load the docker environment configuration from properties file
-		logger.info("Loading docker configuration");
-		BaSyxDockerConfiguration dockerConfig = new BaSyxDockerConfiguration();
-		dockerConfig.loadFromResource(BaSyxDockerConfiguration.DEFAULT_CONFIG_PATH);
-
-		registryUrl = "http://localhost:" + dockerConfig.getHostPort() + contextConfig.getContextPath();
-		logger.info("Registry URL for integration test: " + registryUrl);
-	}
-
-	@Override
-	protected IAASRegistryService getRegistryService() {
-		return new AASRegistryProxy(registryUrl);
-	}
-}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.simple/src/test/resources/.env b/components/basys.components/basyx.components.docker/basyx.components.simple/src/test/resources/.env
deleted file mode 100644
index 21cc7e8..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.simple/src/test/resources/.env
+++ /dev/null
@@ -1,5 +0,0 @@
-BASYX_HOST_PORT=8082
-BASYX_CONTAINER_PORT=4000
-BASYX_IMAGE_NAME=basys/registry-inmemory
-BASYX_CONTAINER_NAME=registry
-BASYX_IMAGE_TAG=0.0.1-SNAPSHOT
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/Dockerfile b/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/Dockerfile
deleted file mode 100644
index 3628774..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/Dockerfile
+++ /dev/null
@@ -1,15 +0,0 @@
-# Add java runtime environment for execution
-FROM java:8-jdk-alpine 
-
-# Copy built jar to image using the jar name specified in the pom.xml (JAR_FILE)
-ARG JAR_FILE
-COPY target/${JAR_FILE} /usr/share/basyxExecutable.jar
-COPY target/lib /usr/share/lib
-COPY src/main/resources/context.properties /usr/share/context.properties
- 
-# Expose the appropriate port. In case of Tomcat, this is 8080.
-ARG PORT
-EXPOSE ${PORT}
- 
-# Start the jar
-CMD java -jar "/usr/share/basyxExecutable.jar" "/usr/share/context.properties"
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/docker-compose.yml b/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/docker-compose.yml
deleted file mode 100644
index f6add3e..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/docker-compose.yml
+++ /dev/null
@@ -1,38 +0,0 @@
-version: '2.1'
-services:
-  registry:
-    image: ${BASYX_IMAGE_NAME}:${BASYX_IMAGE_TAG}
-    container_name: ${BASYX_CONTAINER_NAME}
-    ports:
-      - ${BASYX_HOST_PORT}:${BASYX_CONTAINER_PORT}
-    depends_on:
-      postgres:
-        condition: service_healthy
-# Possibility to embed user-configuration into the docker container 
-#    volumes:
-#      -  ./myConfig/myConfigs.properties:/usr/share/dockerRegistry.properties
-    links:
-      - postgres
-
-  postgres:
-    image: postgres:12.1
-    container_name: postgres
-    environment:
-      - POSTGRES_USER:'postgres'
-      - POSTGRES_PASSWORD:'admin'
-      - POSTGRES_DB=basyx-directory
-    healthcheck:
-      test: ["CMD-SHELL", "pg_isready -U postgres"]
-      interval: 3s
-      timeout: 3s
-      retries: 5
-# Possibility to configure postgres-config into docker container
-#    volumes:
-#      - ./WebContent/WEB-INF/config/postgres/init.sql:/docker-entrypoint-initdb.d/init.sql
-#    ports:
-#      - 5433:5432
-#    expose:
-#      - 5432
-            
-
-      
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/pom.xml b/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/pom.xml
deleted file mode 100644
index 3664f36..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/pom.xml
+++ /dev/null
@@ -1,80 +0,0 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-	<modelVersion>4.0.0</modelVersion>
-
-	<parent>
-		<groupId>org.eclipse.basyx</groupId>
-		<artifactId>basyx.components.docker</artifactId>
-		<version>0.0.1-SNAPSHOT</version>
-    </parent>
-	
-	<artifactId>basyx.components.sqlregistry</artifactId>
-	<name>BaSyx SQL Registry</name>
-	
-	<properties>
-		<basyx.components.executable>org.eclipse.basyx.components.executable.SQLRegistryExecutable</basyx.components.executable>
-	</properties>
-	
-	<packaging>jar</packaging>
-	
-	<build>
-		<!-- Define additional plugins that are not included by default -->
-		<!-- Plugin configuration is done in parent project(s) -->
-		<plugins>
-			<!-- Attach sources to jar file -->
-			<plugin>
-				<groupId>org.apache.maven.plugins</groupId>
-				<artifactId>maven-source-plugin</artifactId>
-			</plugin>
-		</plugins>
-	</build>
-	
-	<dependencies>
-		<!-- Adds additional classes of the BaSys SDK for tests (for TestRegistryProvider) -->
-		<dependency>
-			<groupId>org.eclipse.basyx</groupId>
-			<artifactId>basyx.sdk</artifactId>
-			<classifier>tests</classifier>
-		</dependency>
-	</dependencies>
-	
-	<profiles>
-		<profile>
-			<id>docker</id>
-			<build>
-				<plugins>
-					<!-- Read maven properties from file -->
-					<plugin>
-						<groupId>org.codehaus.mojo</groupId>
-						<artifactId>properties-maven-plugin</artifactId>
-					</plugin>
-				
-					<!-- Copy the dependencies necessary to run the jar -->
-					<plugin>
-						<groupId>org.apache.maven.plugins</groupId>
-						<artifactId>maven-dependency-plugin</artifactId>
-					</plugin>
-				
-					<!-- Build the docker image -->
-					<plugin>
-						<groupId>com.spotify</groupId>
-						<artifactId>dockerfile-maven-plugin</artifactId>
-					</plugin>
-				
-					<!-- Create integration test environment -->
-					<plugin>
-						<groupId>com.dkanejs.maven.plugins</groupId>
-						<artifactId>docker-compose-maven-plugin</artifactId>
-					</plugin>
-					
-					<!-- Run integration tests -->
-					<plugin>    
-						<groupId>org.apache.maven.plugins</groupId>
-						<artifactId>maven-failsafe-plugin</artifactId>
-					</plugin>
-				</plugins>
-			</build>
-		</profile>
-	</profiles>
-</project>
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/main/java/org/eclipse/basyx/components/SQLRegistryComponent.java b/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/main/java/org/eclipse/basyx/components/SQLRegistryComponent.java
deleted file mode 100644
index 3f70a6e..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/main/java/org/eclipse/basyx/components/SQLRegistryComponent.java
+++ /dev/null
@@ -1,49 +0,0 @@
-package org.eclipse.basyx.components;
-
-import org.eclipse.basyx.components.servlet.SQLRegistryServlet;
-import org.eclipse.basyx.vab.protocol.http.server.AASHTTPServer;
-import org.eclipse.basyx.vab.protocol.http.server.BaSyxContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * A registry component based on an SQL database.
- * 
- * @author espen
- */
-public class SQLRegistryComponent {
-	private static Logger logger = LoggerFactory.getLogger(SQLRegistryComponent.class);
-
-	// BaSyx context information
-	private String hostName;
-	private int port;
-	private String path;
-	private String docBasePath;
-	private String sqlPropertyPath;
-
-	// The server with the servlet that will be created
-	private AASHTTPServer server;
-
-	public SQLRegistryComponent(String hostName, int port, String path, String docBasePath, String sqlPropertyPath) {
-		this.sqlPropertyPath = sqlPropertyPath;
-		// Sets the server context
-		this.hostName = hostName;
-		this.port = port;
-		this.path = path;
-		this.docBasePath = docBasePath;
-	}
-
-	/**
-	 * Starts the SQLRegistry at http://${hostName}:${port}/${path}
-	 */
-	public void startComponent() {
-		logger.info("Create the server...");
-		// Init HTTP context and add an InMemoryRegistryServlet according to the configuration
-		BaSyxContext context = new BaSyxContext(path, docBasePath, hostName, port);
-		context.addServletMapping("/*", new SQLRegistryServlet(sqlPropertyPath));
-		server = new AASHTTPServer(context);
-
-		logger.info("Start the server...");
-		server.start();
-	}
-}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/main/java/org/eclipse/basyx/components/executable/SQLRegistryExecutable.java b/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/main/java/org/eclipse/basyx/components/executable/SQLRegistryExecutable.java
deleted file mode 100644
index 67a1d4a..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/main/java/org/eclipse/basyx/components/executable/SQLRegistryExecutable.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package org.eclipse.basyx.components.executable;
-
-import org.eclipse.basyx.components.SQLRegistryComponent;
-import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * A registry servlet based on an SQL database. The servlet therefore provides an implementation
- * for the IAASRegistryService interface with a permanent storage solution. The properties for the 
- * SQL connection will be read from executables.properties in the resource folder.
- * 
- * @author espen
- */
-public class SQLRegistryExecutable {
-	private static Logger logger = LoggerFactory.getLogger(SQLRegistryExecutable.class);
-
-	private SQLRegistryExecutable() {
-	}
-
-	public static void main(String[] args) {
-		logger.info("Starting BaSyx SQL registry");
-
-		// Load configuration
-		BaSyxContextConfiguration config = new BaSyxContextConfiguration();
-		if (args.length > 0 && args[0] instanceof String) {
-			// file path available? => load configs from file
-			config.loadFromFile(args[0]);
-		} else {
-			// fallback: load default configs (in resources)
-			config.loadFromResource(BaSyxContextConfiguration.DEFAULT_CONFIG_PATH);
-		}
-
-		SQLRegistryComponent component = new SQLRegistryComponent(config.getHostname(), config.getPort(),
-				config.getContextPath(), config.getDocBasePath(), "dockerRegistry.properties");
-		component.startComponent();
-	}
-}
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/main/java/org/eclipse/basyx/components/servlet/SQLRegistryServlet.java b/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/main/java/org/eclipse/basyx/components/servlet/SQLRegistryServlet.java
deleted file mode 100644
index ff69ac7..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/main/java/org/eclipse/basyx/components/servlet/SQLRegistryServlet.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package org.eclipse.basyx.components.servlet;
-
-import org.eclipse.basyx.aas.registration.restapi.DirectoryModelProvider;
-import org.eclipse.basyx.components.sqlregistry.SQLRegistry;
-import org.eclipse.basyx.vab.protocol.http.server.VABHTTPInterface;
-
-/**
- * A registry servlet based on an SQL database. The servlet therefore provides an implementation
- * for the IAASRegistryService interface with a permanent storage solution.
- * 
- * @author kuhn, pschorn, espen
- */
-public class SQLRegistryServlet extends VABHTTPInterface<DirectoryModelProvider> {
-	private static final long serialVersionUID = 1L;
-
-	/**
-	 * Provide HTTP interface with JSONProvider to handle serialization and
-	 * SQLDirectoryProvider as backend
-	 */
-	public SQLRegistryServlet() {
-		super(new DirectoryModelProvider(new SQLRegistry()));
-	}
-
-	public SQLRegistryServlet(String customConfigFilePath) {
-		super(new DirectoryModelProvider(new SQLRegistry(customConfigFilePath)));
-	}
-}
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/main/java/org/eclipse/basyx/components/sqlregistry/AASDescriptorMap.java b/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/main/java/org/eclipse/basyx/components/sqlregistry/AASDescriptorMap.java
deleted file mode 100644
index d754f4c..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/main/java/org/eclipse/basyx/components/sqlregistry/AASDescriptorMap.java
+++ /dev/null
@@ -1,129 +0,0 @@
-package org.eclipse.basyx.components.sqlregistry;
-
-import java.util.Collection;
-import java.util.Map;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
-
-/**
- * This is a map implementation for a <String, AASDescriptor> map which is needed
- * by map registries. It is based on an arbitrary <String, Object> map and provides a proxy
- * access to that map by assuming AASDescriptor entries.
- * 
- * @author espen
- *
- */
-public class AASDescriptorMap implements Map<String, AASDescriptor> {
-	/**
-	 * The map all operations of this map are based on
-	 */
-	private Map<String, Object> baseMap;
-
-	/**
-	 * Default constructor taking the base map
-	 * 
-	 * @param baseMap
-	 */
-	public AASDescriptorMap(Map<String, Object> baseMap) {
-		this.baseMap = baseMap;
-	}
-
-	@Override
-	public int size() {
-		return baseMap.size();
-	}
-
-	@Override
-	public boolean isEmpty() {
-		return baseMap.isEmpty();
-	}
-
-	@Override
-	public boolean containsKey(Object key) {
-		return baseMap.containsKey(key);
-	}
-
-	@Override
-	public boolean containsValue(Object value) {
-		return baseMap.containsValue(value);
-	}
-
-	@SuppressWarnings("unchecked")
-	@Override
-	public AASDescriptor get(Object key) {
-		Map<String, Object> mapEntry = (Map<String, Object>) baseMap.get(key);
-		if (mapEntry == null) {
-			return null;
-		} else {
-			return new AASDescriptor(mapEntry);
-		}
-	}
-
-	@Override
-	public AASDescriptor put(String key, AASDescriptor value) {
-		return (AASDescriptor) baseMap.put(key, value);
-	}
-
-	@SuppressWarnings("unchecked")
-	@Override
-	public AASDescriptor remove(Object key) {
-		Map<String, Object> result = (Map<String, Object>) baseMap.remove(key);
-		if (result == null) {
-			return null;
-		} else {
-			return new AASDescriptor(result);
-		}
-	}
-
-	@Override
-	public void putAll(Map<? extends String, ? extends AASDescriptor> m) {
-		baseMap.putAll(m);
-	}
-
-	@Override
-	public void clear() {
-		baseMap.clear();
-	}
-
-	@Override
-	public Set<String> keySet() {
-		return baseMap.keySet();
-	}
-
-	@SuppressWarnings("unchecked")
-	@Override
-	public Collection<AASDescriptor> values() {
-		return baseMap.values().stream()
-				.map(o -> new AASDescriptor((Map<String, Object>) o))
-				.collect(Collectors.toList());
-	}
-
-	@Override
-	public Set<Entry<String, AASDescriptor>> entrySet() {
-		return baseMap.entrySet().stream()
-				.map(e -> new Entry<String, AASDescriptor>() {
-					@Override
-					public AASDescriptor setValue(AASDescriptor value) {
-						return (AASDescriptor) e.setValue(value);
-					}
-
-					@SuppressWarnings("unchecked")
-					@Override
-					public AASDescriptor getValue() {
-						if (e.getValue() == null) {
-							return null;
-						} else {
-							return new AASDescriptor((Map<String, Object>) e.getValue());
-						}
-					}
-
-					@Override
-					public String getKey() {
-						return e.getKey();
-					}
-				}).collect(Collectors.toSet());
-	}
-
-}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/main/java/org/eclipse/basyx/components/sqlregistry/SQLRegistry.java b/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/main/java/org/eclipse/basyx/components/sqlregistry/SQLRegistry.java
deleted file mode 100644
index 17f2729..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/main/java/org/eclipse/basyx/components/sqlregistry/SQLRegistry.java
+++ /dev/null
@@ -1,78 +0,0 @@
-package org.eclipse.basyx.components.sqlregistry;
-
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.util.Map;
-
-import javax.servlet.ServletException;
-
-import org.eclipse.basyx.aas.registration.memory.MapRegistry;
-import org.eclipse.basyx.components.configuration.BaSyxSQLConfiguration;
-import org.eclipse.basyx.tools.sqlproxy.SQLRootElement;
-
-/**
- * Implements a local registry based on an SQL database
- * 
- * @author espen
- *
- */
-public class SQLRegistry extends MapRegistry {
-	private static final String DEFAULT_SQL_CONFIG_PATH = "registry.properties";
-
-	/**
-	 * Receives the path of the configuration.properties file in it's constructor.
-	 * 
-	 * @param configFilePath
-	 */
-	public SQLRegistry(String configFilePath) {
-		super(new AASDescriptorMap(createRootMap(configFilePath)));
-	}
-
-	/**
-	 * Constructor using default sql connections
-	 */
-	public SQLRegistry() {
-		this(DEFAULT_SQL_CONFIG_PATH);
-	}
-
-	/**
-	 * Creates a SQLRegistry from a sql configuration
-	 */
-	public SQLRegistry(BaSyxSQLConfiguration configuration) {
-		super(new AASDescriptorMap(createRootMap(configuration)));
-	}
-
-	private static Map<String, Object> createRootMap(String configFilePath) {
-		BaSyxSQLConfiguration config = new BaSyxSQLConfiguration();
-		config.loadFromResource(configFilePath);
-		return createRootMap(config);
-	}
-
-	private static Map<String, Object> createRootMap(BaSyxSQLConfiguration config) {
-		SQLRootElement sqlRootElement = initSQLConnection(config);
-		sqlRootElement.drop();
-		sqlRootElement.create();
-
-		return sqlRootElement.createMap(sqlRootElement.getNextIdentifier());
-	}
-
-	/**
-	 * Initialize sqlDriver
-	 * 
-	 * @throws IOException
-	 * @throws FileNotFoundException
-	 * 
-	 * @throws ServletException
-	 */
-	private static final SQLRootElement initSQLConnection(BaSyxSQLConfiguration config) {
-		// SQL parameter
-		String path = config.getPath();
-		String user = config.getUser();
-		String pass = config.getPass();
-		String qryPfx = config.getPrefix();
-		String qDrvCls = config.getDrv();
-
-		// Create SQL driver instance
-		return new SQLRootElement(user, pass, path, qDrvCls, qryPfx, "root_registry");
-	}
-}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/main/resources/context.properties b/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/main/resources/context.properties
deleted file mode 100644
index 7e933a3..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/main/resources/context.properties
+++ /dev/null
@@ -1,3 +0,0 @@
-contextPath=/registry
-contextHostname=localhost
-contextPort=4000
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/main/resources/dockerRegistry.properties b/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/main/resources/dockerRegistry.properties
deleted file mode 100644
index 3464cd4..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/main/resources/dockerRegistry.properties
+++ /dev/null
@@ -1,43 +0,0 @@
-# ##############################################################
-# Directory configuration file
-# ##############################################################
-
-
-
-
-# ##############################################################
-# Directory server configuration
-
-
-# URL and type of uplink server. Forward all requests that we cannot satisfy here to uplink
-# - URL of uplink directory server
-# - Type of uplink server. Currently supported is BASYS (BaSys registry API) or DNS (DNS server processing legalBody tag) 
-cfg.uplink       = 
-cfg.uplink.type  = DNS
-
-
-# Downlink servers, forward matching URI patterns to downlink servers
-# - Match all subunits that end with "is.iese", including "is.iese"
-cfg.downlink.is.pattern   = is.iese
-cfg.downlink.is.directory = http://wherever1
-
-# - Match all subunits that end with "pm.iese", including "pm.iese"
-cfg.downlink.pm.pattern   = pm.iese
-cfg.downlink.pm.directory = http://wherever2
-
-# - Match all subunits that end with ".es.iese", but not "es.iese"
-cfg.downlink.es.pattern   = .es.iese
-cfg.downlink.es.directory = http://wherever3
-
-
-
-
-# ##############################################################
-# SQL database configuration
-
-dbuser             = postgres
-dbpass             = admin
-dburl              = //postgres:5432/basyx-directory?
-
-sqlDriver          = org.postgresql.Driver
-sqlPrefix          = jdbc:postgresql:
diff --git a/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/test/java/org/eclipse/basyx/regression/registry/ITSQLRegistry.java b/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/test/java/org/eclipse/basyx/regression/registry/ITSQLRegistry.java
deleted file mode 100644
index 34afc09..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/test/java/org/eclipse/basyx/regression/registry/ITSQLRegistry.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package org.eclipse.basyx.regression.registry;
-
-import org.eclipse.basyx.aas.registration.api.IAASRegistryService;
-import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
-import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
-import org.eclipse.basyx.components.configuration.BaSyxDockerConfiguration;
-import org.eclipse.basyx.testsuite.regression.aas.registration.TestRegistryProviderSuite;
-import org.junit.BeforeClass;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class ITSQLRegistry extends TestRegistryProviderSuite {
-	private static Logger logger = LoggerFactory.getLogger(ITSQLRegistry.class);
-
-	private static String registryUrl;
-
-	@BeforeClass
-	public static void setUpClass() {
-		logger.info("Running integration test...");
-
-		logger.info("Loading servlet configuration");
-		// Load the servlet configuration inside of the docker configuration from properties file
-		BaSyxContextConfiguration contextConfig = new BaSyxContextConfiguration();
-		contextConfig.loadFromResource(BaSyxContextConfiguration.DEFAULT_CONFIG_PATH);
-
-		// Load the docker environment configuration from properties file
-		logger.info("Loading docker configuration");
-		BaSyxDockerConfiguration dockerConfig = new BaSyxDockerConfiguration();
-		dockerConfig.loadFromResource(BaSyxDockerConfiguration.DEFAULT_CONFIG_PATH);
-
-		registryUrl = "http://localhost:" + dockerConfig.getHostPort() + contextConfig.getContextPath()
-				+ "/api/v1/registry";
-		logger.info("Registry URL for integration test: " + registryUrl);
-	}
-
-	@Override
-	protected IAASRegistryService getRegistryService() {
-		// Create a registry proxy directly pointing to the servlet
-		return new AASRegistryProxy(registryUrl);
-	}
-}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/test/java/org/eclipse/basyx/regression/registry/ITSQLRegistryRaw.java b/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/test/java/org/eclipse/basyx/regression/registry/ITSQLRegistryRaw.java
deleted file mode 100644
index 2c5ed04..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/test/java/org/eclipse/basyx/regression/registry/ITSQLRegistryRaw.java
+++ /dev/null
@@ -1,224 +0,0 @@
-package org.eclipse.basyx.regression.registry;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
-
-import java.io.UnsupportedEncodingException;
-import java.net.URLEncoder;
-import java.util.Collection;
-import java.util.Map;
-
-import javax.ws.rs.NotFoundException;
-
-import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
-import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
-import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
-import org.eclipse.basyx.components.configuration.BaSyxDockerConfiguration;
-import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
-import org.eclipse.basyx.tools.webserviceclient.WebServiceRawClient;
-import org.eclipse.basyx.vab.coder.json.metaprotocol.MetaprotocolHandler;
-import org.eclipse.basyx.vab.coder.json.serialization.DefaultTypeFactory;
-import org.eclipse.basyx.vab.coder.json.serialization.GSONTools;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Test raw http queries to SQL directory provider.
- * 
- * @author espen
- *
- */
-public class ITSQLRegistryRaw {
-	private static Logger logger = LoggerFactory.getLogger(ITSQLRegistry.class);
-
-	/**
-	 * Serialization
-	 */
-	private static final GSONTools serializer = new GSONTools(new DefaultTypeFactory());
-	private static final MetaprotocolHandler handler = new MetaprotocolHandler();
-
-	/**
-	 * Invoke BaSyx service calls via web services
-	 */
-	private static final WebServiceRawClient client = new WebServiceRawClient();
-	private static String registryUrl;
-
-	/**
-	 * AASDescriptor to test
-	 */
-	private static final IIdentifier id1 = new ModelUrn("urn:de.FHG:es.iese:aas:0.98:5:lab:microscope#A-166");
-	private static final String endpoint1 = "www.endpoint.de";
-	private static final AASDescriptor aasDescriptor1 = new AASDescriptor(id1, endpoint1);
-	private static final String serializedDescriptor1 = serializer.serialize(aasDescriptor1);
-	private static final IIdentifier id2 = new ModelUrn("urn:de.FHG:es.iese:aas:0.98:5:lab:microscope#A-167");
-	private static final String endpoint2 = "www.endpoint2.de";
-	private static final String endpoint2b = "www.endpoint2.de";
-	private static final AASDescriptor aasDescriptor2 = new AASDescriptor(id2, endpoint2);
-	private static final AASDescriptor aasDescriptor2b = new AASDescriptor(id2, endpoint2b);
-	private static final String serializedDescriptor2 = serializer.serialize(aasDescriptor2);
-	private static final String serializedDescriptor2b = serializer.serialize(aasDescriptor2b);
-	private static final IIdentifier idUnknown = new ModelUrn("urn:de.FHG:es.iese:aas:0.98:5:lab:microscope#A-168");
-	private static String aasUrl1, aasUrl2, aasUrlUnknown;
-
-	@BeforeClass
-	public static void setUpClass() throws UnsupportedEncodingException {
-		logger.info("Running integration test...");
-
-		logger.info("Loading servlet configuration");
-		// Load the servlet configuration inside of the docker configuration from properties file
-		BaSyxContextConfiguration contextConfig = new BaSyxContextConfiguration();
-		contextConfig.loadFromResource(BaSyxContextConfiguration.DEFAULT_CONFIG_PATH);
-
-		// Load the docker environment configuration from properties file
-		logger.info("Loading docker configuration");
-		BaSyxDockerConfiguration dockerConfig = new BaSyxDockerConfiguration();
-		dockerConfig.loadFromResource(BaSyxDockerConfiguration.DEFAULT_CONFIG_PATH);
-
-		registryUrl = "http://localhost:" + dockerConfig.getHostPort() + contextConfig.getContextPath()
-				+ "/api/v1/registry/";
-		logger.info("Registry URL for integration test: " + registryUrl);
-		aasUrl1 = registryUrl + URLEncoder.encode(id1.getId(), "UTF-8");
-		aasUrl2 = registryUrl + URLEncoder.encode(id2.getId(), "UTF-8");
-		aasUrlUnknown = registryUrl + URLEncoder.encode(idUnknown.getId(), "UTF-8");
-
-		logger.info("Registry URL for integration test: " + registryUrl);
-	}
-
-	@Before
-	public void setUp() {
-		// Post serialized descriptor to register it
-		client.post(registryUrl, serializedDescriptor1);
-		client.post(registryUrl, serializedDescriptor2);
-	}
-
-	@After
-	public void tearDown() throws UnsupportedEncodingException {
-		// Delete AAS registration
-		try {
-			client.delete(aasUrl1);			
-		} catch(NotFoundException e) {}
-		try {
-			client.delete(aasUrl2);			
-		} catch(NotFoundException e) {}
-	}
-
-	/**
-	 * Execute test case that test working calls
-	 */
-	@SuppressWarnings("unchecked")
-	@Test
-	public void testGetterCalls() {
-		// First test - get all locally registered AAS
-		{
-			// Get all locally registered AAS
-			Collection<AASDescriptor> result = getResult(client.get(registryUrl));
-
-			// Check if all AAS are contained in result
-			assertEquals(2, result.size());
-		}
-
-		// Get a specific AAS (1)
-		try {
-			// Get a known AAS by its ID
-			AASDescriptor result = new AASDescriptor((Map<String, Object>) getResult(client.get(aasUrl1)));
-
-			// Check if all AAS are contained in result
-			assertEquals(id1.getId(), result.getIdentifier().getId());
-		} catch (Exception e) {
-			fail("Get specific AAS test case did throw exception:" + e);
-		}
-
-		// Get a specific AAS (2)
-		try {
-			// Get a known AAS by its ID
-			AASDescriptor result = new AASDescriptor((Map<String, Object>) getResult(client.get(aasUrl2)));
-
-			// Check if all AAS are contained in result
-			assertEquals(id2.getId(), result.getIdentifier().getId());
-		} catch (Exception e) {
-			fail("Get specific AAS test case did throw exception:" + e);
-		}
-	}
-
-	/**
-	 * Execute update test case
-	 * 
-	 * @throws UnsupportedEncodingException
-	 */
-	@SuppressWarnings("unchecked")
-	@Test
-	public void testUpdateCall() throws UnsupportedEncodingException {
-		// Update a specific AAS
-		// Update AAS registration
-		client.put(aasUrl2, serializedDescriptor2b);
-
-		// Get a known AAS by its ID
-		AASDescriptor result = new AASDescriptor((Map<String, Object>) getResult(client.get(aasUrl2)));
-		// - Check updated registration
-		assertEquals(endpoint2b, result.getFirstEndpoint());
-	}
-
-	/**
-	 * Execute create/Delete test cases
-	 * 
-	 * @throws UnsupportedEncodingException
-	 */
-	@SuppressWarnings("unchecked")
-	@Test
-	public void testCreateDeleteCall() throws UnsupportedEncodingException {
-		// Update a specific AAS
-		// Delete AAS registration (make sure tests work also if previous test suite
-		// did fail)
-		client.delete(aasUrl2);
-
-		// Try to get deleted AAS, has to throw exception
-		try {
-			getResult(client.get(aasUrl2));
-			fail();
-		} catch(NotFoundException e) {}
-
-		// Create new AAS registration
-		client.post(registryUrl, serializedDescriptor2);
-
-		// Get a known AAS by its ID
-		AASDescriptor result2 = new AASDescriptor((Map<String, Object>) getResult(client.get(aasUrl2)));
-
-		assertEquals(endpoint2, result2.getFirstEndpoint()); // need deep json string compare here
-
-		// Delete AAS registration
-		client.delete(aasUrl2);
-
-		// Try to get deleted AAS, has to throw exception
-		try {
-			getResult(client.get(aasUrl2));
-			fail();
-		} catch(NotFoundException e) {}
-	}
-
-	/**
-	 * Execute test case that test non-working calls
-	 * 
-	 * @throws UnsupportedEncodingException
-	 */
-	@Test(expected = NotFoundException.class)
-	public void testNonWorkingCalls() throws UnsupportedEncodingException {
-		// Get unknown AAS ID, has to throw exception
-		getResult(client.get(aasUrlUnknown));
-		fail();
-	}
-
-	@SuppressWarnings("unchecked")
-	private <T> T getResult(String res) {
-		try {
-			return (T) handler.deserialize(res);
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw new RuntimeException();
-		}
-	}
-
-}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/test/java/org/eclipse/basyx/regression/registry/TestSQLRegistryProvider.java b/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/test/java/org/eclipse/basyx/regression/registry/TestSQLRegistryProvider.java
deleted file mode 100644
index b1e8613..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/test/java/org/eclipse/basyx/regression/registry/TestSQLRegistryProvider.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package org.eclipse.basyx.regression.registry;
-
-import org.eclipse.basyx.aas.registration.api.IAASRegistryService;
-import org.eclipse.basyx.components.sqlregistry.SQLRegistry;
-import org.eclipse.basyx.testsuite.regression.aas.registration.TestRegistryProviderSuite;
-
-/**
- * Test class for a local registry provider based on SQL tables
- * 
- * @author espen
- *
- */
-public class TestSQLRegistryProvider extends TestRegistryProviderSuite {
-
-	@Override
-	protected IAASRegistryService getRegistryService() {
-		return new SQLRegistry("localRegistry.properties");
-	}
-}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/test/resources/.env b/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/test/resources/.env
deleted file mode 100644
index c6adcc2..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/test/resources/.env
+++ /dev/null
@@ -1,5 +0,0 @@
-BASYX_HOST_PORT=8082
-BASYX_CONTAINER_PORT=4000
-BASYX_IMAGE_NAME=basys/registry-sql
-BASYX_CONTAINER_NAME=registry
-BASYX_IMAGE_TAG=0.0.1-SNAPSHOT
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/test/resources/localRegistry.properties b/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/test/resources/localRegistry.properties
deleted file mode 100644
index ffec021..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/test/resources/localRegistry.properties
+++ /dev/null
@@ -1,43 +0,0 @@
-# ##############################################################
-# Directory configuration file
-# ##############################################################
-
-
-
-
-# ##############################################################
-# Directory server configuration
-
-
-# URL and type of uplink server. Forward all requests that we cannot satisfy here to uplink
-# - URL of uplink directory server
-# - Type of uplink server. Currently supported is BASYS (BaSys registry API) or DNS (DNS server processing legalBody tag) 
-cfg.uplink       = 
-cfg.uplink.type  = DNS
-
-
-# Downlink servers, forward matching URI patterns to downlink servers
-# - Match all subunits that end with "is.iese", including "is.iese"
-cfg.downlink.is.pattern   = is.iese
-cfg.downlink.is.directory = http://wherever1
-
-# - Match all subunits that end with "pm.iese", including "pm.iese"
-cfg.downlink.pm.pattern   = pm.iese
-cfg.downlink.pm.directory = http://wherever2
-
-# - Match all subunits that end with ".es.iese", but not "es.iese"
-cfg.downlink.es.pattern   = .es.iese
-cfg.downlink.es.directory = http://wherever3
-
-
-
-
-# ##############################################################
-# SQL database configuration
-
-dbuser             = postgres
-dbpass             = admin
-dburl              = //localhost:5432/basyx-directory? 
-
-sqlDriver          = org.postgresql.Driver
-sqlPrefix          = jdbc:postgresql:
diff --git a/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/Dockerfile b/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/Dockerfile
deleted file mode 100644
index 3628774..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/Dockerfile
+++ /dev/null
@@ -1,15 +0,0 @@
-# Add java runtime environment for execution
-FROM java:8-jdk-alpine 
-
-# Copy built jar to image using the jar name specified in the pom.xml (JAR_FILE)
-ARG JAR_FILE
-COPY target/${JAR_FILE} /usr/share/basyxExecutable.jar
-COPY target/lib /usr/share/lib
-COPY src/main/resources/context.properties /usr/share/context.properties
- 
-# Expose the appropriate port. In case of Tomcat, this is 8080.
-ARG PORT
-EXPOSE ${PORT}
- 
-# Start the jar
-CMD java -jar "/usr/share/basyxExecutable.jar" "/usr/share/context.properties"
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/docker-compose.yml b/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/docker-compose.yml
deleted file mode 100644
index aca4d1b..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/docker-compose.yml
+++ /dev/null
@@ -1,31 +0,0 @@
-version: '3'
-services:
-
-  registry:
-    image: ${BASYX_IMAGE_NAME}:${BASYX_IMAGE_TAG}
-    container_name: ${BASYX_CONTAINER_NAME}
-    ports:
-      - ${BASYX_HOST_PORT}:${BASYX_CONTAINER_PORT}
-#    depends_on:
-#      - postgres
-#    volumes:
-#      -  .\WebContent\WEB-INF\config\directory\sqldirectory\directory.properties:/basys/directory.properties
-#    links:
-#      - postgres
-
-#  postgres:
-#    image: postgres:9.4
-#    container_name: postgres
-#    environment:
-#      - POSTGRES_USER:'postgres'
-#      - POSTGRES_PASSWORD:'admin'
-#      - POSTGRES_DB=basyx-directory
-#    volumes:
-#      - ./WebContent/WEB-INF/config/postgres/init.sql:/docker-entrypoint-initdb.d/init.sql
-#    ports:
-#      - 5433:5432
-#    expose:
-#      - 5432
-            
-
-      
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/pom.xml b/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/pom.xml
deleted file mode 100644
index b8ef81c..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/pom.xml
+++ /dev/null
@@ -1,86 +0,0 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-	<modelVersion>4.0.0</modelVersion>
-	
-	<!--
-		Simple Docker Component
-	 
-		Serves as a template for simple docker components that do not depend on other docker containers.
-		Do NOT use the included in-memory registry in a productive environment - the entries are not stored permanently
-	 -->
-
-	<parent>
-		<groupId>org.eclipse.basyx</groupId>
-		<artifactId>basyx.components.docker</artifactId>
-		<version>0.0.1-SNAPSHOT</version>
-    </parent>
-	
-	<artifactId>basyx.components.xmlAAS</artifactId>
-	<name>BaSyx XML Docker Component</name>
-	
-	<properties>
-		<!--  
-			basyx.components.executable is the executable class with the definition of the public void main(String[]).
-			It is needed when building the jar in the maven-jar-plugin (see basyx.components.docker/pom.xml) 
-		-->
-		<basyx.components.executable>org.eclipse.basyx.components.executable.XMLExecutable</basyx.components.executable>
-	</properties>
-	
-	<packaging>jar</packaging>
-	
-	<!-- Define additional plugins that are not included by default -->
-	<!-- Plugin configuration is done in parent project(s) -->
-	<build>
-		<plugins>
-			<!-- Attach sources to jar file -->
-			<plugin>
-				<groupId>org.apache.maven.plugins</groupId>
-				<artifactId>maven-source-plugin</artifactId>
-			</plugin>
-		</plugins>
-	</build>
-	
-	<profiles>
-		<profile>
-			<!-- 
-				"Docker" profile - do not build & install docker images by default
-				Run "mvn install -Pdocker" in order to include docker  
-			-->
-			<id>docker</id>
-			<build>
-				<plugins>
-					<!-- Read maven properties from file -->
-					<plugin>
-						<groupId>org.codehaus.mojo</groupId>
-						<artifactId>properties-maven-plugin</artifactId>
-					</plugin>
-				
-					<!-- Copy the dependencies necessary to run the jar -->
-					<plugin>
-						<groupId>org.apache.maven.plugins</groupId>
-						<artifactId>maven-dependency-plugin</artifactId>
-					</plugin>
-				
-					<!-- Build the docker image -->
-					<plugin>
-						<groupId>com.spotify</groupId>
-						<artifactId>dockerfile-maven-plugin</artifactId>
-					</plugin>
-				
-					<!-- Create integration test environment -->
-					<plugin>
-						<groupId>com.dkanejs.maven.plugins</groupId>
-						<artifactId>docker-compose-maven-plugin</artifactId>
-					</plugin>
-					
-					<!-- Run integration tests -->
-					<plugin>    
-						<groupId>org.apache.maven.plugins</groupId>
-						<artifactId>maven-failsafe-plugin</artifactId>
-					</plugin>
-				</plugins>
-			</build>
-		</profile>
-	</profiles>
-</project>
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/src/main/java/org/eclipse/basyx/components/XMLAASComponent.java b/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/src/main/java/org/eclipse/basyx/components/XMLAASComponent.java
deleted file mode 100644
index fd4006f..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/src/main/java/org/eclipse/basyx/components/XMLAASComponent.java
+++ /dev/null
@@ -1,123 +0,0 @@
-package org.eclipse.basyx.components;
-
-import java.io.IOException;
-import java.util.Collection;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
-import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
-import org.eclipse.basyx.components.configuration.BaSyxConfiguration;
-import org.eclipse.basyx.components.servlet.aas.AASBundleServlet;
-import org.eclipse.basyx.components.xml.XMLAASBundleFactory;
-import org.eclipse.basyx.support.bundle.AASBundle;
-import org.eclipse.basyx.support.bundle.AASBundleDescriptorFactory;
-import org.eclipse.basyx.vab.protocol.http.server.AASHTTPServer;
-import org.eclipse.basyx.vab.protocol.http.server.BaSyxContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.xml.sax.SAXException;
-
-/**
- * A component that takes an xml file (according to the AAS XML-Schema) and provides the AAS via an HTTP server
- * 
- * @author schnicke, espen
- *
- */
-public class XMLAASComponent {
-	private static Logger logger = LoggerFactory.getLogger(XMLAASComponent.class);
-
-	// The server with the servlet that will be created
-	protected AASHTTPServer server;
-
-	protected Collection<AASBundle> aasBundles;
-
-	protected String hostName;
-	protected int port;
-	protected String path;
-	protected String docBasePath;
-	protected String registryUrl;
-
-	protected XMLAASComponent(String hostName, int port, String path, String docBasePath) {
-		// Sets the server context (still needs to load the bundle)
-		this.hostName = hostName;
-		this.port = port;
-		this.path = path;
-		this.docBasePath = docBasePath;
-	}
-
-	public XMLAASComponent(String hostName, int port, String path, String docBasePath, String xmlPath,
-			String registryUrl) throws ParserConfigurationException, SAXException, IOException {
-		this(hostName, port, path, docBasePath);
-		String xmlContent = BaSyxConfiguration.getResourceString(xmlPath);
-		setAASBundle(new XMLAASBundleFactory(xmlContent).create());
-		setRegistryUrl(registryUrl);
-	}
-
-	protected void setAASBundle(Collection<AASBundle> aasBundles) {
-		this.aasBundles = aasBundles;
-	}
-
-	protected void setRegistryUrl(String registryUrl) {
-		this.registryUrl = registryUrl;
-	}
-
-
-	/**
-	 * Returns the set of AAS descriptors for the AAS contained in the AASX
-	 * 
-	 * @param hostBasePath
-	 *                     the path to the server; helper method for e.g. virtualization
-	 *                     environments
-	 * @return
-	 */
-	public Set<AASDescriptor> retrieveDescriptors(String hostBasePath) {
-		return aasBundles.stream().map(b -> AASBundleDescriptorFactory.createAASDescriptor(b, hostBasePath))
-				.collect(Collectors.toSet());
-	}
-
-	/**
-	 * Returns the set of AAS descriptors for the AAS contained in the AASX
-	 * 
-	 * @return
-	 */
-	public Set<AASDescriptor> retrieveDescriptors() {
-		String hostBasePath = "http://" + hostName + ":" + port + "/" + path;
-		return retrieveDescriptors(hostBasePath);
-	}
-
-	/**
-	 * Starts the AASX component at http://${hostName}:${port}/${path}
-	 * 
-	 * @param hostName
-	 * @param port
-	 * @param path
-	 * @param docBasePath
-	 * @throws IOException
-	 * @throws SAXException
-	 * @throws ParserConfigurationException
-	 */
-	public void startComponent() {
-		logger.info("Create the server...");
-		// Init HTTP context and add an XMLAAServlet according to the configuration
-		BaSyxContext context = new BaSyxContext(path, docBasePath, hostName, port);
-		// Create the Servlet for aas
-		context.addServletMapping("/*", new AASBundleServlet(aasBundles));
-		server = new AASHTTPServer(context);
-
-
-		logger.info("Start the server...");
-		server.start();
-
-		if (registryUrl != null && !registryUrl.isEmpty()) {
-			logger.info("Registering AAS at registry \"" + registryUrl + "\"...");
-			AASRegistryProxy registryProxy = new AASRegistryProxy(registryUrl);
-			Set<AASDescriptor> descriptors = retrieveDescriptors();
-			descriptors.stream().forEach(registryProxy::register);
-		} else {
-			logger.info("No registry specified, skipped registration");
-		}
-	}
-}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/src/main/java/org/eclipse/basyx/components/executable/XMLExecutable.java b/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/src/main/java/org/eclipse/basyx/components/executable/XMLExecutable.java
deleted file mode 100644
index b912e66..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/src/main/java/org/eclipse/basyx/components/executable/XMLExecutable.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package org.eclipse.basyx.components.executable;
-
-import java.io.IOException;
-
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.eclipse.basyx.components.XMLAASComponent;
-import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.xml.sax.SAXException;
-
-/**
- * Starts an HTTP server providing multiple AAS and submodels as described in
- * the XML file specified in the properties file <br />
- * They are made available at <i>localhost:4000/xmlAAS/$aasId/aas</i><br />
- * <br />
- * <b>Please note:</b> Neither the AASs nor the Submodels are added to the
- * registry. Additionally, the Submodel descriptors inside the AAS are missing.
- * <br />
- * There reason for this is, that the executable does not know about the outside
- * context (e.g. docker, ...)!
- * 
- * @author haque, schnicke
- */
-public class XMLExecutable {
-	// Creates a Logger based on the current class
-	private static Logger logger = LoggerFactory.getLogger(XMLExecutable.class);
-
-	public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
-		logger.info("Starting BaSyx XML component");
-
-		// Load configuration
-		BaSyxContextConfiguration config = new BaSyxContextConfiguration();
-		if (args.length > 0 && args[0] instanceof String) {
-			// file path available? => load configs from file
-			config.loadFromFile(args[0]);
-		} else {
-			// fallback: load default configs (in resources)
-			config.loadFromResource(BaSyxContextConfiguration.DEFAULT_CONFIG_PATH);
-		}
-
-		XMLAASComponent component = new XMLAASComponent(config.getHostname(), config.getPort(), config.getContextPath(),
-				config.getDocBasePath(), config.getProperty("xmlPath"), config.getProperty("registry"));
-		component.startComponent();
-	}
-}
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/src/main/java/org/eclipse/basyx/components/servlets/XMLAASServlet.java b/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/src/main/java/org/eclipse/basyx/components/servlets/XMLAASServlet.java
deleted file mode 100644
index e44ac91..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/src/main/java/org/eclipse/basyx/components/servlets/XMLAASServlet.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package org.eclipse.basyx.components.servlets;
-
-import java.io.IOException;
-
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.eclipse.basyx.components.servlet.aas.AASBundleServlet;
-import org.eclipse.basyx.components.xml.XMLAASBundleFactory;
-import org.xml.sax.SAXException;
-
-/**
- * It imports AAS from given XML location provided in the context.properties and
- * maps the AAS to servlet. It also adds the submodels, assets and concept
- * descriptors to the AAS.
- * 
- * 
- * @author haque, schnicke
- */
-public class XMLAASServlet extends AASBundleServlet {
-	private static final long serialVersionUID = -3487515646027982620L;
-
-	public XMLAASServlet(String xmlContent) throws ParserConfigurationException, SAXException, IOException {
-		super(new XMLAASBundleFactory(xmlContent).create());
-	}
-}
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/src/main/resources/context.properties b/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/src/main/resources/context.properties
deleted file mode 100644
index f093e52..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/src/main/resources/context.properties
+++ /dev/null
@@ -1,4 +0,0 @@
-contextPath=/xmlAAS
-contextHostname=localhost
-contextPort=4000
-xmlPath=xml/aas.xml
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/src/main/resources/logback.xml b/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/src/main/resources/logback.xml
deleted file mode 100644
index 86341d6..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/src/main/resources/logback.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
- 
-<configuration>
- 
-  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
-    
-    <!-- Example for a filter, which removes all entries not containing "[TEST]" in the message. -->
-    
-    <!--<filter class="ch.qos.logback.core.filter.EvaluatorFilter">      
-      <evaluator>
-        <expression>return message.contains("[TEST]");</expression>
-      </evaluator>
-      <OnMismatch>DENY</OnMismatch>
-      <OnMatch>NEUTRAL</OnMatch>
-    </filter>-->
-  
-    <encoder>
-      <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{5} - %msg%n</pattern>
-    </encoder>
-  </appender>
-  
-  <root level="INFO">          
-    <appender-ref ref="STDOUT" />
-  </root>  
-   
-</configuration>
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/src/main/resources/xml/aas.xml b/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/src/main/resources/xml/aas.xml
deleted file mode 100644
index 04a32c8..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/src/main/resources/xml/aas.xml
+++ /dev/null
@@ -1,585 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<aas:aasenv xmlns:aas="http://www.admin-shell.io/aas/2/0"
-	xmlns:IEC61360="http://www.admin-shell.io/IEC61360/2/0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-	xsi:schemaLocation="http://www.admin-shell.io/aas/2/0 AAS.xsd
-	http://www.admin-shell.io/IEC61360/2/0 IEC61360.xsd">
-	<aas:assetAdministrationShells>
-		<!-- This AAS is populated with all possible fields -->
-		<aas:assetAdministrationShell>
-			<aas:idShort>aas1</aas:idShort>
-			<aas:category>test_category</aas:category>
-			<aas:description>
-				<aas:langString lang="EN">aas_Description</aas:langString>
-				<aas:langString lang="DE">Beschreibung Verwaltungsschale</aas:langString>
-			</aas:description>
-			<aas:parent>
-				<!-- Parent is currently a String in the Schema. But it should be a Reference. -->
-				<aas:keys>
-					<aas:key idType="IRI" local="false" type="AssetAdministrationShell">aas_parent_id</aas:key>
-				</aas:keys>
-			</aas:parent>
-			<aas:identification idType="IRI">www.admin-shell.io/aas-sample/2/0</aas:identification>
-			<aas:administration>
-				<aas:version>1</aas:version>
-				<aas:revision>0</aas:revision>
-			</aas:administration>
-			<aas:embeddedDataSpecification>
-				<aas:dataSpecificationContent>
-					<aas:dataSpecificationIEC61360>
-						<IEC61360:preferredName>
-							<IEC61360:langString lang="DE">Drehzahl</IEC61360:langString>
-							<IEC61360:langString lang="EN">Rotation Speed</IEC61360:langString>
-						</IEC61360:preferredName>
-						<IEC61360:shortName>
-							<IEC61360:langString lang="DE">N</IEC61360:langString>
-						</IEC61360:shortName>
-						<IEC61360:unit>1/min</IEC61360:unit>
-						<IEC61360:unitId>
-							<IEC61360:keys>
-								<IEC61360:key idType="IRDI" local="false" type="GlobalReference">
-									0173-1#05-AAA650#002
-								</IEC61360:key>
-							</IEC61360:keys>
-						</IEC61360:unitId>
-						<IEC61360:valueFormat>NR1..5</IEC61360:valueFormat>
-					</aas:dataSpecificationIEC61360>
-				</aas:dataSpecificationContent>
-				<aas:dataSpecification>
-					<aas:keys>
-						<aas:key idType="IRI" local="false" type="GlobalReference">www.admin-shell.io/DataSpecificationTemplates/DataSpecificationIEC61360</aas:key>
-					</aas:keys>
-				</aas:dataSpecification>
-			</aas:embeddedDataSpecification>
-			<aas:derivedFrom>
-				<aas:keys>
-					<aas:key type="ReferenceElement" local="false" idType="IRI">http://pk.festo.com/3s7plfdrs35</aas:key>
-				</aas:keys>
-			</aas:derivedFrom>
-			<aas:assetRef>
-				<aas:keys>
-					<aas:key type="Asset" local="false" idType="IRI">http://pk.festo.com/3s7plfdrs35</aas:key>
-				</aas:keys>
-			</aas:assetRef>
-			<aas:submodelRefs>
-				<aas:submodelRef>
-					<aas:keys>
-						<aas:key type="Submodel" local="true" idType="IRI">http://www.zvei.de/demo/submodel/12345679</aas:key>
-					</aas:keys>
-				</aas:submodelRef>
-			</aas:submodelRefs>
-			<aas:views>
-				<!-- This View is populated with all possible fields -->
-				<aas:view>
-					<aas:idShort>SampleView</aas:idShort>
-					<aas:category>test_categogy</aas:category>
-					<aas:description>
-						<aas:langString lang="EN">View_Description</aas:langString>
-					</aas:description>
-					<aas:parent>
-						<!-- Parent is currently a String in the Schema. But it should be a Reference. -->
-						<aas:keys>
-							<aas:key idType="IRI" local="false" type="Submodel">view_parent_id</aas:key>
-						</aas:keys>
-					</aas:parent>
-					<aas:semanticId>
-						<aas:keys>
-							<aas:key idType="IRI" local="false" type="Submodel">view_semantic_id</aas:key>
-						</aas:keys>
-					</aas:semanticId>
-					<aas:embeddedDataSpecification>
-						<aas:dataSpecificationContent>
-							<aas:dataSpecificationIEC61360>
-								<IEC61360:preferredName>
-									<IEC61360:langString lang="DE">Drehzahl</IEC61360:langString>
-									<IEC61360:langString lang="EN">Rotation Speed</IEC61360:langString>
-								</IEC61360:preferredName>
-								<IEC61360:shortName>
-									<IEC61360:langString lang="DE">N</IEC61360:langString>
-								</IEC61360:shortName>
-								<IEC61360:unit>1/min</IEC61360:unit>
-								<IEC61360:unitId>
-									<IEC61360:keys>
-										<IEC61360:key local="false" type="GlobalReference" idType="IRDI">0173-1#05-AAA650#002</IEC61360:key>
-									</IEC61360:keys>
-								</IEC61360:unitId>
-								<IEC61360:valueFormat>NR1..5</IEC61360:valueFormat>
-							</aas:dataSpecificationIEC61360>
-						</aas:dataSpecificationContent>
-						<aas:dataSpecification>
-							<aas:keys>
-								<aas:key idType="IRI" local="false" type="GlobalReference">www.admin-shell.io/DataSpecificationTemplates/DataSpecificationIEC61360</aas:key>
-							</aas:keys>
-						</aas:dataSpecification>
-					</aas:embeddedDataSpecification>
-					<aas:containedElements>
-						<aas:containedElementRef>
-							<aas:keys>
-								<aas:key type="Submodel" local="true" idType="IRI">"http://www.zvei.de/demo/submodel/12345679"</aas:key>
-								<aas:key type="Property" local="true" idType="IdShort">rotationSpeed</aas:key>
-							</aas:keys>
-						</aas:containedElementRef>
-					</aas:containedElements>
-				</aas:view>
-				<!-- This is a View with only the minimal required information in it. To test for Nullpointers and such. -->
-				<aas:view>
-					<aas:idShort>EmptyView</aas:idShort>
-					<aas:containedElements></aas:containedElements>
-				</aas:view>
-			</aas:views>
-			<aas:conceptDictionaries>
-				<aas:conceptDictionary>
-					<aas:idShort>SampleDic</aas:idShort>
-					<aas:conceptDescriptionRefs>
-						<aas:conceptDescriptionRef>
-							<aas:keys>
-								<aas:key type="ConceptDescription" local="true" idType="IRI">www.festo.com/dic/08111234</aas:key>
-							</aas:keys>
-						</aas:conceptDescriptionRef>
-					</aas:conceptDescriptionRefs>
-				</aas:conceptDictionary>
-			</aas:conceptDictionaries>
-		</aas:assetAdministrationShell>
-		<!-- This is an AAS with only the minimal required information in it. To test for Nullpointers and such. -->
-		<aas:assetAdministrationShell>
-			<aas:idShort>asset_admin_shell</aas:idShort>
-			<aas:identification idType="IRI">www.admin-shell.io/aas-sample/1/1</aas:identification>
-			<aas:assetRef>
-				<aas:keys>
-					<aas:key type="Asset" local="false" idType="IRI">http://pk.festo.com/3s7plfdrs35</aas:key>
-				</aas:keys>
-			</aas:assetRef>
-		</aas:assetAdministrationShell>
-	</aas:assetAdministrationShells>
-	<aas:assets>
-		<!-- This Asset is populated with all possible fields -->
-		<aas:asset>
-			<aas:idShort>3s7plfdrs35_asset1</aas:idShort>
-			<aas:category>asset1_categogy</aas:category>
-			<aas:description>
-				<aas:langString lang="EN">asset1_Description</aas:langString>
-			</aas:description>
-			<aas:parent>
-				<!-- Parent is currently a String in the Schema. But it should be a Reference. -->
-				<aas:keys>
-					<aas:key idType="IRI" local="false" type="Asset">asset_parent_id</aas:key>
-				</aas:keys>
-			</aas:parent>
-			<aas:identification idType="IRI">http://pk.festo.com/3s7plfdrs35</aas:identification>
-			<aas:administration>
-				<aas:version>1</aas:version>
-				<aas:revision>0</aas:revision>
-			</aas:administration>
-			<aas:embeddedDataSpecification>
-				<aas:dataSpecificationContent>
-					<aas:dataSpecificationIEC61360>
-						<IEC61360:preferredName>
-							<IEC61360:langString lang="DE">Drehzahl</IEC61360:langString>
-							<IEC61360:langString lang="EN">Rotation Speed</IEC61360:langString>
-						</IEC61360:preferredName>
-						<IEC61360:shortName>
-							<IEC61360:langString lang="DE">N</IEC61360:langString>
-						</IEC61360:shortName>
-						<IEC61360:unit>1/min</IEC61360:unit>
-						<IEC61360:unitId>
-							<IEC61360:keys>
-								<IEC61360:key local="false" type="GlobalReference" idType="IRDI">0173-1#05-AAA650#002</IEC61360:key>
-							</IEC61360:keys>
-						</IEC61360:unitId>
-						<IEC61360:valueFormat>NR1..5</IEC61360:valueFormat>
-					</aas:dataSpecificationIEC61360>
-				</aas:dataSpecificationContent>
-				<aas:dataSpecification>
-					<aas:keys>
-						<aas:key idType="IRI" local="false" type="GlobalReference">www.admin-shell.io/DataSpecificationTemplates/DataSpecificationIEC61360</aas:key>
-					</aas:keys>
-				</aas:dataSpecification>
-			</aas:embeddedDataSpecification>
-			<aas:assetIdentificationModelRef>
-				<aas:keys>
-					<aas:key type="ConceptDescription" local="true" idType="IRI">www.festo.com/dic/08111234</aas:key>
-				</aas:keys>
-			</aas:assetIdentificationModelRef>
-			<aas:kind>Instance</aas:kind>
-		</aas:asset>
-		<aas:asset>
-			<aas:idShort>emptyAsset</aas:idShort>
-			<aas:identification idType="IRI">http://pk.festo.com/q30j38dlajx</aas:identification>
-		</aas:asset>
-	</aas:assets>
-	<aas:submodels>
-		<!-- This Submodel is populated with all possible fields -->
-		<aas:submodel>
-			<aas:idShort>submodel1</aas:idShort>
-			<aas:category>submodel1_categogy</aas:category>
-			<aas:description>
-				<aas:langString lang="EN">submode1_decription</aas:langString>
-			</aas:description>
-			<aas:parent>
-				<!-- Parent is currently a String in the Schema. But it should be a Reference. -->
-				<aas:keys>
-					<aas:key idType="IRI" local="false" type="Submodel">submodel_parent_id</aas:key>
-				</aas:keys>
-			</aas:parent>
-			<aas:identification idType="IRI">http://www.zvei.de/demo/submodel/12345679</aas:identification>
-			<aas:administration>
-				<aas:version>1</aas:version>
-				<aas:revision>0</aas:revision>
-			</aas:administration>
-			<aas:kind>Instance</aas:kind>
-			<aas:semanticId>
-				<aas:keys>
-					<aas:key idType="IRI" local="false" type="Submodel">http://www.zvei.de/demo/submodelDefinitions/87654346</aas:key>
-				</aas:keys>
-			</aas:semanticId>
-			<aas:qualifier>
-				<aas:qualifiers>
-					<aas:formula>
-						<aas:dependsOnRefs>
-							<aas:reference>
-								<aas:keys>
-									<aas:key local="false" type="GlobalReference" idType="IRDI">qualifier_reference</aas:key>
-								</aas:keys>
-							</aas:reference>
-						</aas:dependsOnRefs>
-					</aas:formula>
-				</aas:qualifiers>
-				<aas:qualifiers>
-					<aas:qualifier>
-						<aas:valueId>
-							<aas:keys>
-								<aas:key idType="IRI" local="false" type="Submodel">http://www.zvei.de/demo/submodelDefinitions/87654346</aas:key>
-							</aas:keys>
-						</aas:valueId>
-						<aas:value>qualifierValue</aas:value>
-						<aas:type>qualifierType</aas:type>
-						<aas:valueType>valueType</aas:valueType>
-						<aas:semanticId>
-							<aas:keys>
-								<aas:key idType="IRI" local="false" type="GlobalReference">http://www.zvei.de/demo/submodelDefinitions/87654346</aas:key>
-							</aas:keys>
-						</aas:semanticId>
-					</aas:qualifier>
-				</aas:qualifiers>
-			</aas:qualifier>
-			<aas:embeddedDataSpecification>
-				<aas:dataSpecificationContent>
-					<aas:dataSpecificationIEC61360>
-						<IEC61360:preferredName>
-							<IEC61360:langString lang="DE">Drehzahl</IEC61360:langString>
-							<IEC61360:langString lang="EN">Rotation Speed</IEC61360:langString>
-						</IEC61360:preferredName>
-						<IEC61360:shortName>
-							<IEC61360:langString lang="DE">N</IEC61360:langString>
-						</IEC61360:shortName>
-						<IEC61360:unit>1/min</IEC61360:unit>
-						<IEC61360:unitId>
-							<IEC61360:keys>
-								<IEC61360:key local="false" type="GlobalReference" idType="IRDI">0173-1#05-AAA650#002</IEC61360:key>
-							</IEC61360:keys>
-						</IEC61360:unitId>
-						<IEC61360:valueFormat>NR1..5</IEC61360:valueFormat>
-					</aas:dataSpecificationIEC61360>
-				</aas:dataSpecificationContent>
-				<aas:dataSpecification>
-					<aas:keys>
-						<aas:key idType="IRI" local="false" type="GlobalReference">www.admin-shell.io/DataSpecificationTemplates/DataSpecificationIEC61360</aas:key>
-					</aas:keys>
-				</aas:dataSpecification>
-			</aas:embeddedDataSpecification>
-			<aas:submodelElements>
-				<aas:submodelElement>
-					<aas:property>
-						<aas:idShort>rotationSpeed</aas:idShort>
-						<aas:category>VARIABLE</aas:category>
-						<aas:semanticId>
-							<aas:keys>
-								<aas:key idType="IRI" type="ConceptDescription" local="true">www.festo.com/dic/08111234</aas:key>
-							</aas:keys>
-						</aas:semanticId>
-						<aas:qualifier>
-							<aas:qualifiers>
-								<aas:qualifier>
-									<aas:valueId>
-										<aas:keys>
-											<aas:key idType="IRI" local="false" type="Submodel">http://www.zvei.de/demo/submodelDefinitions/87654346</aas:key>
-										</aas:keys>
-									</aas:valueId>
-									<aas:value>qualifierValue</aas:value>
-									<aas:type>qualifierType</aas:type>
-									<aas:valueType>valueType</aas:valueType>
-									<aas:semanticId>
-										<aas:keys>
-											<aas:key idType="IRI" local="false" type="GlobalReference">http://www.zvei.de/demo/submodelDefinitions/87654346</aas:key>
-										</aas:keys>
-									</aas:semanticId>
-								</aas:qualifier>
-							</aas:qualifiers>
-						</aas:qualifier>
-						<aas:embeddedDataSpecification>
-							<aas:dataSpecificationContent>
-								<aas:dataSpecificationIEC61360>
-									<IEC61360:preferredName>
-										<IEC61360:langString lang="DE">Drehzahl</IEC61360:langString>
-										<IEC61360:langString lang="EN">Rotation Speed</IEC61360:langString>
-									</IEC61360:preferredName>
-									<IEC61360:shortName>
-										<IEC61360:langString lang="DE">N</IEC61360:langString>
-									</IEC61360:shortName>
-									<IEC61360:unit>1/min</IEC61360:unit>
-									<IEC61360:unitId>
-										<IEC61360:keys>
-											<IEC61360:key local="false" type="GlobalReference" idType="IRDI">0173-1#05-AAA650#002</IEC61360:key>
-										</IEC61360:keys>
-									</IEC61360:unitId>
-									<IEC61360:valueFormat>NR1..5</IEC61360:valueFormat>
-								</aas:dataSpecificationIEC61360>
-							</aas:dataSpecificationContent>
-							<aas:dataSpecification>
-								<aas:keys>
-									<aas:key idType="IRI" local="false" type="GlobalReference">www.admin-shell.io/DataSpecificationTemplates/DataSpecificationIEC61360</aas:key>
-								</aas:keys>
-							</aas:dataSpecification>
-						</aas:embeddedDataSpecification>
-						<aas:value>2000</aas:value>
-						<aas:valueType>double</aas:valueType>
-					</aas:property>
-				</aas:submodelElement>
-				<aas:submodelElement>
-					<aas:property>
-						<aas:idShort>emptyDouble</aas:idShort>
-						<aas:valueType>double</aas:valueType>
-					</aas:property>
-				</aas:submodelElement>
-				<aas:submodelElement>
-					<aas:basicEvent>
-						<aas:idShort>basic_event_id</aas:idShort>
-						<aas:observed>
-							<aas:keys>
-								<aas:key idType="IRI" local="false" type="Submodel">http://www.zvei.de/demo/submodelDefinitions/87654346</aas:key>
-							</aas:keys>
-						</aas:observed>
-					</aas:basicEvent>
-				</aas:submodelElement>
-				<aas:submodelElement>
-					<aas:entity>
-						<aas:idShort>entity_id</aas:idShort>
-						<aas:assetRef>
-							<aas:keys>
-								<aas:key idType="IRI" local="false" type="Submodel">http://www.zvei.de/demo/submodelDefinitions/87654346</aas:key>
-							</aas:keys>
-						</aas:assetRef>
-						<aas:entityType>CoManagedEntity</aas:entityType>
-						<aas:statements>
-							<!-- XML Schema currently supports only one statement, but multiple should be supported -->
-							<aas:submodelElement>
-								<aas:file>
-									<aas:idShort>file_ID</aas:idShort>
-									<aas:mimeType>file_mimetype</aas:mimeType>
-									<aas:value>file_value</aas:value>
-								</aas:file>
-							</aas:submodelElement>
-							<aas:submodelElement>
-								<aas:range>
-									<aas:idShort>range_id</aas:idShort>
-									<aas:min>10</aas:min>
-									<aas:valueType>int</aas:valueType>
-								</aas:range>
-							</aas:submodelElement>
-						</aas:statements>
-					</aas:entity>
-				</aas:submodelElement>
-				<aas:submodelElement>
-					<aas:multiLanguageProperty>
-						<aas:idShort>multi_language_property_id</aas:idShort>
-						<aas:valueId>
-							<aas:keys>
-								<aas:key local="false" type="GlobalReference" idType="IRDI">0173-1#05-AAA650#002</aas:key>
-							</aas:keys>
-						</aas:valueId>
-						<aas:value>
-							<aas:langString lang="DE">Eine Beschreibung auf deutsch</aas:langString>
-							<aas:langString lang="EN">A description in english</aas:langString>
-						</aas:value>
-					</aas:multiLanguageProperty>
-				</aas:submodelElement>
-				<aas:submodelElement>
-					<aas:range>
-						<aas:idShort>range_id</aas:idShort>
-						<aas:max>10</aas:max>
-						<aas:min>1</aas:min>
-						<aas:valueType>int</aas:valueType>
-					</aas:range>
-				</aas:submodelElement>
-				<aas:submodelElement>
-					<aas:file>
-						<aas:idShort>file_id</aas:idShort>
-						<aas:mimeType>file_mimetype</aas:mimeType>
-						<aas:value>file_value</aas:value>
-					</aas:file>
-				</aas:submodelElement>
-				<aas:submodelElement>
-					<aas:blob>
-						<aas:idShort>blob_id</aas:idShort>
-						<aas:value>YmxvYit2YWx1ZQ==</aas:value>
-						<aas:mimeType>blob_mimetype</aas:mimeType>
-					</aas:blob>
-				</aas:submodelElement>
-				<aas:submodelElement>
-					<aas:referenceElement>
-						<aas:idShort>reference_ELE_ID</aas:idShort>
-						<aas:value>
-							<aas:keys>
-								<aas:key local="false" type="GlobalReference" idType="IRDI">0173-1#05-AAA650#002</aas:key>
-							</aas:keys>
-						</aas:value>
-					</aas:referenceElement>
-				</aas:submodelElement>
-				<aas:submodelElement>
-					<aas:submodelElementCollection>
-						<aas:idShort>submodelElementCollection_ID</aas:idShort>
-						<aas:allowDuplicates>true</aas:allowDuplicates>
-						<aas:ordered>false</aas:ordered>
-						<aas:value>
-							<aas:submodelElement>
-								<aas:file>
-									<aas:idShort>file_ID</aas:idShort>
-									<aas:mimeType>file_mimetype</aas:mimeType>
-									<aas:value>file_value</aas:value>
-								</aas:file>
-							</aas:submodelElement>
-							<aas:submodelElement>
-								<aas:blob>
-									<aas:idShort>blob_id</aas:idShort>
-									<aas:value>YmxvYit2YWx1ZQ==</aas:value>
-									<aas:mimeType>blob_mimetype</aas:mimeType>
-								</aas:blob>
-							</aas:submodelElement>
-						</aas:value>
-					</aas:submodelElementCollection>
-				</aas:submodelElement>
-				<aas:submodelElement>
-					<aas:relationshipElement>
-						<aas:idShort>relationshipElement_ID</aas:idShort>
-						<aas:first>
-							<aas:keys>
-								<aas:key local="false" type="GlobalReference" idType="IRDI">0173-1#05-AAA650#001</aas:key>
-							</aas:keys>
-						</aas:first>
-						<aas:second>
-							<aas:keys>
-								<aas:key local="false" type="GlobalReference" idType="IRDI">0173-1#05-AAA650#002</aas:key>
-							</aas:keys>
-						</aas:second>
-					</aas:relationshipElement>
-				</aas:submodelElement>
-				<aas:submodelElement>
-					<aas:operation>
-						<aas:idShort>operation_ID</aas:idShort>
-						<aas:inoutputVariable>
-							<aas:operationVariable>
-								<aas:value>
-									<aas:referenceElement>
-										<aas:idShort>reference_ELE_ID2</aas:idShort>
-										<aas:value>
-											<aas:keys>
-												<aas:key local="false" type="GlobalReference" idType="IRDI">0173-1#05-AAA650#003</aas:key>
-											</aas:keys>
-										</aas:value>
-									</aas:referenceElement>
-								</aas:value>
-							</aas:operationVariable>
-						</aas:inoutputVariable>
-						<aas:inputVariable>
-							<!-- The schema only allows one opVar in inputVariable, one in outputVariable and one in inoutputVariable. The Metamodel allows 0..* in each -->
-							<!-- To be able to have multiple Vars they are surrounded by <aas:operationVariable>. This is also violating the Schema. -->
-							<aas:operationVariable>
-								<aas:value>
-									<aas:file>
-										<aas:idShort>file_ID</aas:idShort>
-										<aas:mimeType>file_mimetype</aas:mimeType>
-										<aas:value>file_value</aas:value>
-									</aas:file>
-								</aas:value>
-							</aas:operationVariable>
-							<aas:operationVariable>
-								<aas:value>
-									<aas:blob>
-										<aas:idShort>blob_ID</aas:idShort>
-										<aas:value>YmxvYit2YWx1ZQ==</aas:value>
-										<aas:mimeType>blob_mimetype</aas:mimeType>
-									</aas:blob>
-								</aas:value>
-							</aas:operationVariable>
-						</aas:inputVariable>
-						<aas:outputVariable>
-							<aas:operationVariable>
-								<aas:value>
-									<aas:referenceElement>
-										<aas:idShort>reference_ELE_ID</aas:idShort>
-										<aas:value>
-											<aas:keys>
-												<aas:key local="false" type="GlobalReference" idType="IRDI">0173-1#05-AAA650#002</aas:key>
-											</aas:keys>
-										</aas:value>
-									</aas:referenceElement>
-								</aas:value>
-							</aas:operationVariable>
-						</aas:outputVariable>
-					</aas:operation>
-				</aas:submodelElement>
-			</aas:submodelElements>
-		</aas:submodel>
-	</aas:submodels>
-	<aas:conceptDescriptions>
-		<!-- This ConceptDescription is populated with all possible fields -->
-		<aas:conceptDescription>
-			<aas:idShort>conceptDescription1</aas:idShort>
-			<aas:category>cs_category</aas:category>
-			<aas:description>
-				<aas:langString lang="EN">conceptDescription_Description</aas:langString>
-			</aas:description>
-			<aas:parent>
-				<!-- Parent is currently a String in the Schema. But it should be a Reference. -->
-				<aas:keys>
-					<aas:key idType="IRI" local="false" type="ConceptDescription">cs_parent_id</aas:key>
-				</aas:keys>
-			</aas:parent>
-			<aas:identification idType="IRI">www.festo.com/dic/08111234</aas:identification>
-			<aas:administration>
-				<aas:version>1</aas:version>
-				<aas:revision>0</aas:revision>
-			</aas:administration>
-			<aas:embeddedDataSpecification>
-				<aas:dataSpecificationContent>
-					<aas:dataSpecificationIEC61360>
-						<IEC61360:preferredName>
-							<IEC61360:langString lang="DE">Drehzahl</IEC61360:langString>
-							<IEC61360:langString lang="EN">Rotation Speed</IEC61360:langString>
-						</IEC61360:preferredName>
-						<IEC61360:shortName>
-							<IEC61360:langString lang="DE">N</IEC61360:langString>
-						</IEC61360:shortName>
-						<IEC61360:unit>1/min</IEC61360:unit>
-						<IEC61360:unitId>
-							<IEC61360:keys>
-								<IEC61360:key local="false" type="GlobalReference" idType="IRDI">0173-1#05-AAA650#002</IEC61360:key>
-							</IEC61360:keys>
-						</IEC61360:unitId>
-						<IEC61360:valueFormat>NR1..5</IEC61360:valueFormat>
-					</aas:dataSpecificationIEC61360>
-				</aas:dataSpecificationContent>
-				<aas:dataSpecification>
-					<aas:keys>
-						<aas:key idType="IRI" local="false" type="GlobalReference">www.admin-shell.io/DataSpecificationTemplates/DataSpecificationIEC61360</aas:key>
-					</aas:keys>
-				</aas:dataSpecification>
-			</aas:embeddedDataSpecification>
-			<aas:isCaseOf>
-				<aas:keys>
-					<aas:key idType="IRI" type="ConceptDescription" local="true">www.festo.com/dic/08111234</aas:key>
-					<aas:key idType="IRI" type="ConceptDescription" local="true">www.festo.com/dic/08111234_2</aas:key>
-				</aas:keys>
-			</aas:isCaseOf>
-		</aas:conceptDescription>
-	</aas:conceptDescriptions>
-</aas:aasenv>
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/src/test/java/org/eclipse/basyx/regression/xmlAAS/ITInXMLAAS.java b/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/src/test/java/org/eclipse/basyx/regression/xmlAAS/ITInXMLAAS.java
deleted file mode 100644
index 3e15324..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/src/test/java/org/eclipse/basyx/regression/xmlAAS/ITInXMLAAS.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package org.eclipse.basyx.regression.xmlAAS;
-
-import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
-import org.eclipse.basyx.components.configuration.BaSyxDockerConfiguration;
-import org.junit.BeforeClass;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class ITInXMLAAS extends XMLAASSuite {
-	private static Logger logger = LoggerFactory.getLogger(ITInXMLAAS.class);
-
-	@BeforeClass
-	public static void setUpClass() {
-		logger.info("Running integration test...");
-
-		logger.info("Loading servlet configuration");
-		// Load the servlet configuration inside of the docker configuration from properties file
-		BaSyxContextConfiguration contextConfig = new BaSyxContextConfiguration();
-		contextConfig.loadFromResource(BaSyxContextConfiguration.DEFAULT_CONFIG_PATH);
-
-		// Load the docker environment configuration from properties file
-		logger.info("Loading docker configuration");
-		BaSyxDockerConfiguration dockerConfig = new BaSyxDockerConfiguration();
-		dockerConfig.loadFromResource(BaSyxDockerConfiguration.DEFAULT_CONFIG_PATH);
-
-		aasEndpoint = "http://localhost:" + dockerConfig.getHostPort() + contextConfig.getContextPath() + "/" + aasShortId + "/aas";
-		smEndpoint = "http://localhost:" + dockerConfig.getHostPort() + contextConfig.getContextPath() + "/" + aasShortId + "/aas/submodels/" + smShortId + "/submodel";
-
-		logger.info("AAS URL for integration test: " + aasEndpoint);
-	}
-}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/src/test/java/org/eclipse/basyx/regression/xmlAAS/TestXMLAAS.java b/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/src/test/java/org/eclipse/basyx/regression/xmlAAS/TestXMLAAS.java
deleted file mode 100644
index 7fd042d..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/src/test/java/org/eclipse/basyx/regression/xmlAAS/TestXMLAAS.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package org.eclipse.basyx.regression.xmlAAS;
-
-import java.io.IOException;
-
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
-import org.eclipse.basyx.components.executable.XMLExecutable;
-import org.junit.BeforeClass;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.xml.sax.SAXException;
-
-public class TestXMLAAS extends XMLAASSuite {
-	private static Logger logger = LoggerFactory.getLogger(TestXMLAAS.class);
-
-	@BeforeClass
-	public static void setUpClass() throws ParserConfigurationException, SAXException, IOException {
-		XMLExecutable.main(new String[] {});
-
-		BaSyxContextConfiguration config = new BaSyxContextConfiguration();
-		config.loadFromResource(BaSyxContextConfiguration.DEFAULT_CONFIG_PATH);
-
-		aasEndpoint = "http://" + config.getHostname() + ":" + config.getPort() + "/" + config.getContextPath() + "/" + aasShortId + "/aas";
-		smEndpoint = "http://" + config.getHostname() + ":" + config.getPort() + "/" + config.getContextPath() + "/" + aasShortId + "/aas/submodels/" + smShortId + "/submodel";
-		logger.info("AAS URL for servlet test: " + aasEndpoint);
-	}
-}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/src/test/java/org/eclipse/basyx/regression/xmlAAS/XMLAASSuite.java b/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/src/test/java/org/eclipse/basyx/regression/xmlAAS/XMLAASSuite.java
deleted file mode 100644
index 19105ff..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/src/test/java/org/eclipse/basyx/regression/xmlAAS/XMLAASSuite.java
+++ /dev/null
@@ -1,91 +0,0 @@
-package org.eclipse.basyx.regression.xmlAAS;
-
-import static org.junit.Assert.assertEquals;
-
-import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
-import org.eclipse.basyx.aas.metamodel.connected.ConnectedAssetAdministrationShell;
-import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
-import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
-import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
-import org.eclipse.basyx.aas.registration.api.IAASRegistryService;
-import org.eclipse.basyx.aas.registration.memory.InMemoryRegistry;
-import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
-import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
-import org.eclipse.basyx.vab.protocol.api.IConnectorProvider;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * Suite for testing that the XMLAAS servlet is set up correctly. The tests here
- * can be used by the servlet test itself and the integration test
- * 
- * @author schnicke
- *
- */
-public class XMLAASSuite {
-
-	protected IAASRegistryService registry;
-
-	protected static final String aasShortId = "aas1";
-	protected static final IIdentifier aasId = new ModelUrn("www.admin-shell.io/aas-sample/2/0");
-	protected static final IIdentifier smId = new ModelUrn("http://www.zvei.de/demo/submodel/12345679");
-	protected static final String smShortId = "submodel1";
-
-	// Has to be individualized by each test inheriting from this suite
-	protected static String aasEndpoint;
-	protected static String smEndpoint;
-
-	private ConnectedAssetAdministrationShellManager manager;
-
-	/**
-	 * Before each test, a dummy registry is created and an AAS is added in the
-	 * registry
-	 */
-	@Before
-	public void setUp() {
-		// Create a dummy registry to test integration of XML AAS
-		registry = new InMemoryRegistry();
-		AASDescriptor descriptor = new AASDescriptor(aasShortId, aasId, aasEndpoint);
-		descriptor.addSubmodelDescriptor(new SubmodelDescriptor(smShortId, smId, smEndpoint));
-		registry.register(descriptor);
-
-		// Create a ConnectedAssetAdministrationShell using a
-		// ConnectedAssetAdministrationShellManager
-		IConnectorProvider connectorProvider = new HTTPConnectorProvider();
-		manager = new ConnectedAssetAdministrationShellManager(registry, connectorProvider);
-	}
-
-	@Test
-	public void testGetSingleAAS() throws Exception {
-		ConnectedAssetAdministrationShell connectedAssetAdministrationShell = getConnectedAssetAdministrationShell();
-		assertEquals(aasShortId, connectedAssetAdministrationShell.getIdShort());
-	}
-
-	@Test
-	public void testGetSingleSubmodel() throws Exception {
-		ISubModel subModel = getConnectedSubmodel();
-		assertEquals(smShortId, subModel.getIdShort());
-	}
-
-	/**
-	 * Gets the connected Asset Administration Shell
-	 * 
-	 * @return connected AAS
-	 * @throws Exception
-	 */
-	private ConnectedAssetAdministrationShell getConnectedAssetAdministrationShell() throws Exception {
-		return manager.retrieveAAS(aasId);
-	}
-
-	/**
-	 * Gets the connected Submodel
-	 * 
-	 * @return connected SM
-	 * @throws Exception
-	 */
-	private ISubModel getConnectedSubmodel() {
-		return manager.retrieveSubModel(aasId, smId);
-	}
-
-}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/src/test/resources/.env b/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/src/test/resources/.env
deleted file mode 100644
index 226a4c9..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.xmlAAS/src/test/resources/.env
+++ /dev/null
@@ -1,5 +0,0 @@
-BASYX_HOST_PORT=8083
-BASYX_CONTAINER_PORT=4000
-BASYX_IMAGE_NAME=basys/aas-xml
-BASYX_CONTAINER_NAME=aas-xml
-BASYX_IMAGE_TAG=0.0.1-SNAPSHOT
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/pom.xml b/components/basys.components/basyx.components.docker/pom.xml
index 332d4c8..6afe083 100644
--- a/components/basys.components/basyx.components.docker/pom.xml
+++ b/components/basys.components/basyx.components.docker/pom.xml
@@ -5,7 +5,7 @@
 	<parent>
 		<groupId>org.eclipse.basyx</groupId>
 		<artifactId>basyx.components</artifactId>
-		<version>0.0.1-SNAPSHOT</version>
+		<version>1.0.0</version>
     </parent>
 	
 	<artifactId>basyx.components.docker</artifactId>
@@ -15,10 +15,7 @@
 
 	<!-- Includes all components in this project as separated modules -->
 	<modules>
-		<module>basyx.components.simple</module>
-		<module>basyx.components.sqlregistry</module>
-		<module>basyx.components.xmlAAS</module>
-		<module>basyx.components.AASX</module>
+		<module>basyx.components.registry</module>
     	<module>basyx.components.AASServer</module>
   </modules>
 	
@@ -106,10 +103,17 @@
 					</executions>
 					<configuration>
 						<repository>${BASYX_IMAGE_NAME}</repository>
-						<tag>${project.version}</tag>
+						<tag>${BASYX_IMAGE_TAG}</tag>
 						<buildArgs>
 							<JAR_FILE>${project.build.finalName}.jar</JAR_FILE>
 							<PORT>${BASYX_CONTAINER_PORT}</PORT>
+							<!-- The system property/env keys for basyx configuration files -->
+							<CONTEXT_CONFIG_KEY>BASYX_CONTEXT</CONTEXT_CONFIG_KEY>
+							<REGISTRY_CONFIG_KEY>BASYX_REGISTRY</REGISTRY_CONFIG_KEY>
+							<AAS_CONFIG_KEY>BASYX_AAS</AAS_CONFIG_KEY>
+							<MONGODB_CONFIG_KEY>BASYX_MONGODB</MONGODB_CONFIG_KEY>
+							<DOCKER_CONFIG_KEY>BASYX_DOCKER</DOCKER_CONFIG_KEY>
+							<SQL_CONFIG_KEY>BASYX_SQL</SQL_CONFIG_KEY>
 						</buildArgs>
 					</configuration>
 				</plugin>
@@ -174,7 +178,7 @@
 		<dependency>
 			<groupId>org.eclipse.basyx</groupId>
 			<artifactId>basyx.components.lib</artifactId>
-			<version>${project.version}</version>
+			<version>1.0.0</version>
 		</dependency>
 	</dependencies>
 </project>
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.lib/pom.xml b/components/basys.components/basyx.components.lib/pom.xml
index f34dbff..1cf5fe2 100644
--- a/components/basys.components/basyx.components.lib/pom.xml
+++ b/components/basys.components/basyx.components.lib/pom.xml
@@ -5,7 +5,7 @@
 	<parent>
 		<groupId>org.eclipse.basyx</groupId>
 		<artifactId>basyx.components</artifactId>
-		<version>0.0.1-SNAPSHOT</version>
+		<version>1.0.0</version>
     </parent>
 	
 	<artifactId>basyx.components.lib</artifactId>
@@ -13,18 +13,6 @@
 	
 	<packaging>jar</packaging>
 	
- 	<repositories>
-		<repository>
-			<id>mule</id>
-			<name>Mule Repository</name>
-			<url>https://repository.mulesoft.org/nexus/content/groups/public/</url>
-			<layout>default</layout>
-			<snapshots>
-				<enabled>false</enabled>
-			</snapshots>
-		</repository>
-	</repositories>
-	
 	<!-- Define additional plugins that are not included by default -->
 	<build>
 		<plugins>
@@ -43,107 +31,8 @@
 			<artifactId>postgresql</artifactId>
 			<version>42.2.2</version>
 		</dependency>
-
-		<dependency>
-			<groupId>javax.enterprise</groupId>
-			<artifactId>cdi-api</artifactId>
-			<version>2.0</version>
-			<scope>provided</scope>
-		</dependency>
 		
 		<dependency>
-			<groupId>javax.el</groupId>
-			<artifactId>el-api</artifactId>
-			<version>2.2</version>
-		</dependency>
-		
-		<dependency>
-			<groupId>javax.inject</groupId>
-			<artifactId>javax.inject</artifactId>
-			<version>1</version>
-		</dependency>
-
-		<dependency>
-			<groupId>javax.json</groupId>
-			<artifactId>javax.json-api</artifactId>
-			<version>1.0</version>
-		</dependency>
-
-		<dependency>
-			<groupId>javax.xml.bind</groupId>
-			<artifactId>jaxb-api</artifactId>
-			<version>2.3.0</version>
-		</dependency>
-		
-		<dependency>
-			<groupId>javax.annotation</groupId>
-			<artifactId>javax.annotation-api</artifactId>
-			<version>1.3.2</version>
-		</dependency>
-		
-		<dependency>
-			<groupId>javax.persistence</groupId>
-			<artifactId>persistence-api</artifactId>
-			<version>1.0.2</version>
-		</dependency>
-
-		<dependency>
-			<groupId>javax.validation</groupId>
-			<artifactId>validation-api</artifactId>
-			<version>2.0.1.Final</version>
-		</dependency>
-
-		<dependency>
-			<groupId>javax.servlet</groupId>
-			<artifactId>javax.servlet-api</artifactId>
-			<version>3.1.0</version>
-			<scope>provided</scope>
-		</dependency>
-
-		<dependency>
-			<groupId>javassist</groupId>
-			<artifactId>javassist</artifactId>
-			<version>3.12.1.GA</version>
-		</dependency>
-		
-		<dependency>
-			<groupId>org.jboss.spec.javax.interceptor</groupId>
-			<artifactId>jboss-interceptors-api_1.1_spec</artifactId>
-			<version>1.0.1.Final</version>
-		</dependency>
-		
-		<dependency>
-			<groupId>org.osgi</groupId>
-			<artifactId>org.osgi.core</artifactId>
-			<version>4.2.0</version>
-			<scope>provided</scope>
-		</dependency>
-	
-		<dependency>
-			<groupId>org.glassfish.hk2</groupId>
-			<artifactId>hk2-api</artifactId>
-			<version>2.5.0</version>
-		</dependency>
-
-		<dependency>
-			<groupId>org.glassfish.hk2</groupId>
-			<artifactId>osgi-resource-locator</artifactId>
-			<version>1.0.1</version>
-		</dependency>
-	
-		<dependency>
-			<groupId>org.glassfish.hk2.external</groupId>
-			<artifactId>aopalliance-repackaged</artifactId>
-			<version>2.5.0-b42</version>
-		</dependency>
-
-		<dependency>
-			<groupId>org.eclipse</groupId>
-			<artifactId>yasson</artifactId>
-			<version>1.0.2</version>
-		</dependency>
-
-		<dependency>
   			<groupId>org.camunda.bpm</groupId>
   			<artifactId>camunda-engine</artifactId>
   			<version>7.12.0</version>
@@ -167,33 +56,6 @@
 			<version>1.4.197</version>
 		</dependency>
 
-		<!-- Add from local repository because jar cannot be found on maven central -->
-		<dependency>
-		    <groupId>javax.xml.xquery</groupId>
-		    <artifactId>xqj-api</artifactId>
-		    <version>1.0</version>
-		</dependency>
-
-
-		<!-- Add from external repository because jar cannot be found on maven central -->
-		<dependency>
-			<groupId>net.sf.saxon</groupId>
-			<artifactId>saxon-xqj</artifactId>
-			<version>8.9.0.4</version>
-		</dependency>
-
-		<dependency>
-			<groupId>net.sf.saxon</groupId>
-			<artifactId>Saxon-HE</artifactId>
-			<version>9.5.1-5</version>
-		</dependency>
-
-		<dependency>
-			<groupId>com.google.code.gson</groupId>
-			<artifactId>gson</artifactId>
-			<version>2.8.5</version>
-		</dependency>
-		
 		<dependency>
 	        <groupId>com.zaxxer</groupId>
 	        <artifactId>HikariCP</artifactId>
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/IComponent.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/IComponent.java
new file mode 100644
index 0000000..82f6a08
--- /dev/null
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/IComponent.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.components;
+
+/**
+ * Common interfaces for all components allowing starting/stopping the component
+ * 
+ * @author schnicke
+ *
+ */
+public interface IComponent {
+
+	/**
+	 * Starts the component
+	 */
+	public void startComponent();
+
+	/**
+	 * Shuts down the component
+	 */
+	public void stopComponent();
+}
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/cfgprovider/CFGSubModelProvider.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/cfgprovider/CFGSubModelProvider.java
deleted file mode 100644
index fceb07d..0000000
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/cfgprovider/CFGSubModelProvider.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package org.eclipse.basyx.components.cfgprovider;
-
-import java.util.Map;
-
-import org.eclipse.basyx.components.provider.BaseConfiguredProvider;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElement;
-import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-
-
-/**
- * Asset administration shell sub model provider that exports a properties file
- * 
- * @author kuhn
- *
- */
-public class CFGSubModelProvider extends BaseConfiguredProvider {
-
-	/**
-	 * Initiates a logger using the current class
-	 */
-	private static final Logger logger = LoggerFactory.getLogger(CFGSubModelProvider.class);
-
-	/**
-	 * Constructor
-	 */
-	public CFGSubModelProvider(Map<Object, Object> cfgValues) {
-		// Call base constructor
-		super(cfgValues);
-
-		// Add properties
-		for (String key: getConfiguredProperties(cfgValues)) {
-			// Create properties
-			SubmodelElement elem = createSubmodelElement(key, cfgValues.get(key), cfgValues);
-			createValue("submodel/" + SubmodelElementProvider.ELEMENTS, elem);
-			
-			// Debug output
-			logger.debug("Adding configured property: "+key.toString()+" = "+cfgValues.get(key));
-		}
-	}
-}
-
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/cfgprovider/RawCFGSubModelProvider.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/cfgprovider/RawCFGSubModelProvider.java
deleted file mode 100644
index 405f33e..0000000
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/cfgprovider/RawCFGSubModelProvider.java
+++ /dev/null
@@ -1,81 +0,0 @@
-package org.eclipse.basyx.components.cfgprovider;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.eclipse.basyx.components.provider.BaseConfiguredProvider;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Asset administration shell sub model provider that exports a properties file
- * 
- * @author kuhn
- *
- */
-public class RawCFGSubModelProvider extends BaseConfiguredProvider {
-	
-	/**
-	 * Initiates a logger using the current class
-	 */
-	private static final Logger logger = LoggerFactory.getLogger(RawCFGSubModelProvider.class);
-
-	private static final String FTYPE = "$ftype";
-
-	/**
-	 * Constructor
-	 */
-	@SuppressWarnings("unchecked")
-	public RawCFGSubModelProvider(Map<Object, Object> cfgValues) {
-		// Call base constructor -> creates base submodelData from cfgValues
-		super(cfgValues);
-
-		// Load properties
-		for (Object key : cfgValues.keySet()) {
-			// Do not put meta data keys into map
-			if (((String) key).endsWith(FTYPE))
-				continue;
-
-			// Get path to element
-			String[] path = splitPath((String) key);
-
-			// Create path
-			Map<String, Object> scope = new HashMap<>();
-			scope = submodelData;
-			for (int i = 0; i < path.length - 1; i++) {
-				if (!scope.containsKey(path[i]))
-					scope.put(path[i], new HashMap<String, Object>());
-				scope = (Map<String, Object>) scope.get(path[i]);
-			}
-
-			// Get and optionally convert value
-			Object value = cfgValues.get(key);
-			// - Cast value if requested by user
-			if (cfgValues.get(key + FTYPE) != null)
-				switch ((String) cfgValues.get(key + FTYPE)) {
-				case "int":
-					value = Integer.parseInt((String) value);
-					break;
-				case "boolean":
-					value = Boolean.parseBoolean((String) value);
-					break;
-				case "float":
-					value = Float.parseFloat((String) value);
-					break;
-
-				default:
-					logger.error("Unknown type:" + cfgValues.get(key + FTYPE));
-				}
-
-			logger.debug("Putting:" + key + " = " + cfgValues.get(key) + " as " + value.getClass().getName());
-
-			scope.put(path[path.length - 1], value);
-		}
-
-		// Push data to provider
-		setSubmodel(submodelData);
-
-		// Print configuration values
-		logger.debug("CFG exported");
-	}
-}
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/BaSyxConfiguration.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/BaSyxConfiguration.java
index 6ad9aba..08ae715 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/BaSyxConfiguration.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/BaSyxConfiguration.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.components.configuration;
 
 import java.io.FileInputStream;
@@ -5,8 +14,10 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.nio.charset.StandardCharsets;
+import java.util.List;
 import java.util.Map;
 import java.util.Properties;
+import java.util.stream.Collectors;
 
 import org.apache.commons.io.IOUtils;
 import org.slf4j.Logger;
@@ -53,6 +64,29 @@
 	}
 
 	/**
+	 * Load the configuration from a path relative to the current folder
+	 * 
+	 * @param filePath Path to the resource in the application folder
+	 */
+	public void loadFileOrDefaultResource(String fileKey, String defaultResource) {
+		// Try to load property that points to the configuration file (e.g. java -DfileKey=yx.properties [...])
+		String configFilePath = System.getProperty(fileKey);
+		if ( configFilePath == null || configFilePath.isEmpty() ) {
+			// Try to load environment variable that points to the configuration file
+			configFilePath = System.getenv(fileKey);
+		}
+
+		// Load context configuration
+		if (configFilePath != null && !configFilePath.isEmpty()) {
+			// file path available? => load configs from file
+			loadFromFile(configFilePath);
+		} else {
+			// fallback: load default configs (by resource)
+			loadFromResource(defaultResource);
+		}
+	}
+
+	/**
 	 * Load the configuration from an input stream
 	 * 
 	 * @param input the input stream containing the properties
@@ -105,6 +139,26 @@
 	}
 
 	/**
+	 * Method for subclasses to read specific environment variables
+	 * 
+	 * @param prefix     The prefix of each of the environment variables
+	 * @param properties The name of the properties in the config and environment (with prefix)
+	 */
+	protected void loadFromEnvironmentVariables(String prefix, String... properties) {
+		try {
+			for (String propName : properties) {
+				String result = System.getenv(prefix + propName);
+				if (result != null) {
+					logger.info("Environment - " + propName + ": " + result);
+					setProperty(propName, result);
+				}
+			}
+		} catch (SecurityException e) {
+			logger.info("Reading configs from environment is not permitted");
+		}
+	}
+
+	/**
 	 * Sets a property, if it is contained in this configuration
 	 * 
 	 * @param name  The name of the property
@@ -115,6 +169,16 @@
 	}
 
 	/**
+	 * Returns all contained properties that begin with a specific prefix
+	 * 
+	 * @param prefix The filtered prefix (e.g. "aas.")
+	 * @return The list of all contained properties that begin with the prefix
+	 */
+	public List<String> getProperties(String prefix) {
+		return values.keySet().stream().filter(key -> key.startsWith(prefix)).collect(Collectors.toList());
+	}
+
+	/**
 	 * Queries a property
 	 */
 	public String getProperty(String name) {
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/BaSyxContextConfiguration.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/BaSyxContextConfiguration.java
index e9381a7..129667d 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/BaSyxContextConfiguration.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/BaSyxContextConfiguration.java
@@ -1,10 +1,19 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.components.configuration;
 
 import java.util.HashMap;
 import java.util.Map;
 
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.eclipse.basyx.vab.modelprovider.VABPathTools;
+import org.eclipse.basyx.vab.protocol.http.server.BaSyxContext;
 
 /**
  * Represents a BaSyx http servlet configuration for a BaSyxContext,
@@ -14,58 +23,134 @@
  *
  */
 public class BaSyxContextConfiguration extends BaSyxConfiguration {
-	
-	/**
-	 * Initiates a logger using the current class
-	 */
-	private static final Logger logger = LoggerFactory.getLogger(BaSyxContextConfiguration.class);
-	
+	// Prefix for environment variables
+	public static final String ENV_PREFIX = "BaSyxContext_";
+
 	// Default BaSyx Context configuration
-	public static final String DEFAULT_CONTEXTPATH = "/basys.sdk";
+	public static final String DEFAULT_CONTEXTPATH = "basys.sdk";
 	public static final String DEFAULT_DOCBASE = System.getProperty("java.io.tmpdir");
 	public static final String DEFAULT_HOSTNAME = "localhost";
 	public static final int DEFAULT_PORT = 4000;
 
-	private static final String CONTEXTPATH = "contextPath";
-	private static final String DOCBASE = "contextDocPath";
-	private static final String HOSTNAME = "contextHostname";
-	private static final String PORT = "contextPort";
+	public static final String CONTEXTPATH = "contextPath";
+	public static final String DOCBASE = "contextDocPath";
+	public static final String HOSTNAME = "contextHostname";
+	public static final String PORT = "contextPort";
 
 	// The default path for the context properties file
 	public static final String DEFAULT_CONFIG_PATH = "context.properties";
 
+	// The default key for variables pointing to the configuration file
+	public static final String DEFAULT_FILE_KEY = "BASYX_CONTEXT";
+
 	public static Map<String, String> getDefaultProperties() {
 		Map<String, String> defaultProps = new HashMap<>();
 		defaultProps.put(CONTEXTPATH, DEFAULT_CONTEXTPATH);
-		logger.debug("DEFAULT " + DOCBASE + " - " + DEFAULT_DOCBASE);
 		defaultProps.put(DOCBASE, DEFAULT_DOCBASE);
 		defaultProps.put(HOSTNAME, DEFAULT_HOSTNAME);
 		defaultProps.put(PORT, Integer.toString(DEFAULT_PORT));
 		return defaultProps;
 	}
 
+	/**
+	 * Empty Constructor - use default values
+	 */
 	public BaSyxContextConfiguration() {
 		super(getDefaultProperties());
 	}
 
+	/**
+	 * Constructor with predefined value map
+	 */
 	public BaSyxContextConfiguration(Map<String, String> values) {
 		super(values);
 	}
 
+	/**
+	 * Constructor with initial configuration - docBasePath and hostname are default values
+	 * 
+	 * @param port        The port that will be occupied
+	 * @param contextPath The subpath for this context
+	 */
+	public BaSyxContextConfiguration(int port, String contextPath) {
+		this();
+		setPort(port);
+		setContextPath(contextPath);
+	}
+
+	/**
+	 * Constructor with initial configuration - docBasePath and hostname are default values
+	 * 
+	 * @param contextPath The subpath for this context
+	 * @param docBasePath The local base path for the documents
+	 * @param hostname    The hostname
+	 * @param port        The port that will be occupied
+	 */
+	public BaSyxContextConfiguration(String contextPath, String docBasePath, String hostname, int port) {
+		this();
+		setContextPath(contextPath);
+		setDocBasePath(docBasePath);
+		setHostname(hostname);
+		setPort(port);
+	}
+
+	public void loadFromEnvironmentVariables() {
+		String[] properties = { CONTEXTPATH, DOCBASE, HOSTNAME, PORT };
+		loadFromEnvironmentVariables(ENV_PREFIX, properties);
+	}
+
+	public void loadFromDefaultSource() {
+		loadFileOrDefaultResource(DEFAULT_FILE_KEY, DEFAULT_CONFIG_PATH);
+		loadFromEnvironmentVariables();
+	}
+
+	public BaSyxContext createBaSyxContext() {
+		String reqContextPath = getContextPath();
+		String reqDocBasePath = getDocBasePath();
+		String hostName = getHostname();
+		int reqPort = getPort();
+		return new BaSyxContext(reqContextPath, reqDocBasePath, hostName, reqPort);
+	}
+
 	public String getContextPath() {
 		return getProperty(CONTEXTPATH);
 	}
 
+	public void setContextPath(String contextPath) {
+		setProperty(CONTEXTPATH, VABPathTools.stripSlashes(contextPath));
+	}
+
 	public String getDocBasePath() {
-		logger.debug("DEFAULT " + DOCBASE + " -- " + getProperty(DOCBASE));
 		return getProperty(DOCBASE);
 	}
 
+	public void setDocBasePath(String docBasePath) {
+		setProperty(DOCBASE, docBasePath);
+	}
+
 	public String getHostname() {
 		return getProperty(HOSTNAME);
 	}
 
+	public void setHostname(String hostname) {
+		setProperty(HOSTNAME, hostname);
+	}
+
 	public int getPort() {
 		return Integer.parseInt(getProperty(PORT));
 	}
+
+	public void setPort(int port) {
+		setProperty(PORT, Integer.toString(port));
+	}
+
+	public String getUrl() {
+		String contextPath = getContextPath();
+		String base = "http://" + getHostname() + ":" + getPort();
+		if (contextPath.isEmpty()) {
+			return base;
+		} else {
+			return VABPathTools.concatenatePaths(base, contextPath);
+		}
+	}
 }
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/BaSyxDockerConfiguration.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/BaSyxDockerConfiguration.java
index 72c4cca..8370580 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/BaSyxDockerConfiguration.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/BaSyxDockerConfiguration.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.components.configuration;
 
 import java.util.HashMap;
@@ -10,20 +19,26 @@
  *
  */
 public class BaSyxDockerConfiguration extends BaSyxConfiguration {
-	// Default BaSyx Context configuration
-	private static final int DEFAULT_HOSTPORT = 8082;
-	private static final int DEFAULT_CONTAINERPORT = 4000;
-	private static final String DEFAULT_IMAGENAME = "basys/component";
-	private static final String DEFAULT_CONTAINERNAME = "component";
+	// Prefix for environment variables
+	public static final String ENV_PREFIX = "BaSyxDocker_";
 
-	private static final String HOSTPORT = "BASYX_HOST_PORT";
-	private static final String CONTAINERPORT = "BASYX_CONTAINER_PORT";
-	private static final String IMAGENAME = "BASYX_IMAGE_NAME";
-	private static final String CONTAINERNAME = "BASYX_CONTAINER_NAME";
+	// Default BaSyx Context configuration
+	public static final int DEFAULT_HOSTPORT = 8082;
+	public static final int DEFAULT_CONTAINERPORT = 4000;
+	public static final String DEFAULT_IMAGENAME = "basys/component";
+	public static final String DEFAULT_CONTAINERNAME = "component";
+
+	public static final String HOSTPORT = "BASYX_HOST_PORT";
+	public static final String CONTAINERPORT = "BASYX_CONTAINER_PORT";
+	public static final String IMAGENAME = "BASYX_IMAGE_NAME";
+	public static final String CONTAINERNAME = "BASYX_CONTAINER_NAME";
 
 	// The default path for the context properties file
 	public static final String DEFAULT_CONFIG_PATH = ".env";
 
+	// The default key for variables pointing to the configuration file
+	public static final String DEFAULT_FILE_KEY = "BASYX_DOCKER";
+
 	public static Map<String, String> getDefaultProperties() {
 		Map<String, String> defaultProps = new HashMap<>();
 		defaultProps.put(HOSTPORT, Integer.toString(DEFAULT_HOSTPORT));
@@ -34,27 +49,75 @@
 		return defaultProps;
 	}
 
+	/**
+	 * Empty Constructor - use default values
+	 */
 	public BaSyxDockerConfiguration() {
 		super(getDefaultProperties());
 	}
 
+	/**
+	 * Constructor with predefined value map
+	 */
 	public BaSyxDockerConfiguration(Map<String, String> values) {
 		super(values);
 	}
 
+	/**
+	 * Constructor with initial configuration
+	 * 
+	 * @param hostPort      The port for the HOST
+	 * @param containerPort The port for the CONTAINER
+	 * @param imageName     The name of the image
+	 * @param containerName The name of the container
+	 */
+	public BaSyxDockerConfiguration(int hostPort, int containerPort, String imageName, String containerName) {
+		this();
+		setHostPort(hostPort);
+		setContainerPort(containerPort);
+		setImageName(imageName);
+		setContainerName(containerName);
+	}
+
+	public void loadFromEnvironmentVariables() {
+		String[] properties = { HOSTPORT, CONTAINERPORT, IMAGENAME, CONTAINERNAME };
+		loadFromEnvironmentVariables(ENV_PREFIX, properties);
+	}
+
+	public void loadFromDefaultSource() {
+		loadFileOrDefaultResource(DEFAULT_FILE_KEY, DEFAULT_CONFIG_PATH);
+		loadFromEnvironmentVariables();
+	}
+
 	public int getHostPort() {
 		return Integer.parseInt(getProperty(HOSTPORT));
 	}
 
+	public void setHostPort(int hostPort) {
+		setProperty(HOSTPORT, Integer.toString(hostPort));
+	}
+
 	public int getContainerPort() {
 		return Integer.parseInt(getProperty(CONTAINERPORT));
 	}
 
+	public void setContainerPort(int containerPort) {
+		setProperty(CONTAINERPORT, Integer.toString(containerPort));
+	}
+
 	public String getImageName() {
 		return getProperty(IMAGENAME);
 	}
 
+	public void setImageName(String imageName) {
+		setProperty(IMAGENAME, imageName);
+	}
+
 	public String getContainerName() {
 		return getProperty(CONTAINERNAME);
 	}
+
+	public void setContainerName(String containerName) {
+		setProperty(CONTAINERNAME, containerName);
+	}
 }
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/BaSyxMongoDBConfiguration.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/BaSyxMongoDBConfiguration.java
new file mode 100644
index 0000000..a0e0136
--- /dev/null
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/BaSyxMongoDBConfiguration.java
@@ -0,0 +1,169 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.components.configuration;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Represents a BaSyx configuration for a MongoDB connection.
+ * 
+ * @author espen
+ *
+ */
+public class BaSyxMongoDBConfiguration extends BaSyxConfiguration {
+	// Prefix for environment variables
+	public static final String ENV_PREFIX = "BaSyxMongoDB_";
+
+	// Default BaSyx SQL configuration
+	public static final String DEFAULT_CONNECTIONURL = "mongodb://127.0.0.1:27017/";
+	public static final String DEFAULT_DATABASE = "admin";
+	public static final String DEFAULT_REGISTRY_COLLECTION = "basyxregistry";
+	public static final String DEFAULT_AAS_COLLECTION = "basyxaas";
+	public static final String DEFAULT_SUBMODEL_COLLECTION = "basyxsubmodel";
+
+	public static final String DATABASE = "dbname";
+	public static final String CONNECTIONURL = "dbconnectionstring";
+	public static final String REGISTRY_COLLECTION = "dbcollectionRegistry";
+	public static final String AAS_COLLECTION = "dbcollectionAAS";
+	public static final String SUBMODEL_COLLECTION = "dbcollectionSubmodels";
+
+	// The default path for the context properties file
+	public static final String DEFAULT_CONFIG_PATH = "mongodb.properties";
+
+	// The default key for variables pointing to the configuration file
+	public static final String DEFAULT_FILE_KEY = "BASYX_MONGODB";
+
+	public static Map<String, String> getDefaultProperties() {
+		Map<String, String> defaultProps = new HashMap<>();
+		defaultProps.put(CONNECTIONURL, DEFAULT_CONNECTIONURL);
+		defaultProps.put(DATABASE, DEFAULT_DATABASE);
+		defaultProps.put(REGISTRY_COLLECTION, DEFAULT_REGISTRY_COLLECTION);
+		defaultProps.put(AAS_COLLECTION, DEFAULT_AAS_COLLECTION);
+		defaultProps.put(SUBMODEL_COLLECTION, DEFAULT_SUBMODEL_COLLECTION);
+
+		return defaultProps;
+	}
+
+	/**
+	 * Constructor with predefined value map
+	 */
+	public BaSyxMongoDBConfiguration(Map<String, String> values) {
+		super(values);
+	}
+
+	/**
+	 * Empty Constructor - use default values
+	 */
+	public BaSyxMongoDBConfiguration() {
+		super(getDefaultProperties());
+	}
+
+	/**
+	 * Constructor with initial configuration
+	 * 
+	 * @param connectionUrl      Connection-URL for the mongodb
+	 * @param database           The database that shall be used
+	 * @param registryCollection Collection name for the registry data
+	 * @param aasCollection      Collection name for the AAS data
+	 * @param submodelCollection Collection name for the submodel data
+	 */
+	public BaSyxMongoDBConfiguration(String connectionUrl, String database, String registryCollection,
+			String aasCollection, String submodelCollection) {
+		this();
+		setConnectionUrl(connectionUrl);
+		setDatabase(database);
+		setRegistryCollection(registryCollection);
+		setAASCollection(aasCollection);
+		setSubmodelCollection(submodelCollection);
+	}
+
+	/**
+	 * Constructor with initial configuration (without registry collection)
+	 * 
+	 * @param connectionUrl      Connection-URL for the mongodb
+	 * @param database           The database that shall be used
+	 * @param aasCollection      Collection name for the AAS data
+	 * @param submodelCollection Collection name for the submodel data
+	 */
+	public BaSyxMongoDBConfiguration(String connectionUrl, String database, String aasCollection,
+			String submodelCollection) {
+		this();
+		setConnectionUrl(connectionUrl);
+		setDatabase(database);
+		setAASCollection(aasCollection);
+		setSubmodelCollection(submodelCollection);
+	}
+
+	/**
+	 * Constructor with initial configuration (without aas collection)
+	 * 
+	 * @param connectionUrl      Connection-URL for the mongodb
+	 * @param database           The database that shall be used
+	 * @param aasCollection      Collection name for the AAS data
+	 * @param submodelCollection Collection name for the submodel data
+	 */
+	public BaSyxMongoDBConfiguration(String connectionUrl, String database, String registryCollection) {
+		this();
+		setConnectionUrl(connectionUrl);
+		setDatabase(database);
+		setRegistryCollection(registryCollection);
+	}
+
+	public void loadFromEnvironmentVariables() {
+		String[] properties = { DATABASE, CONNECTIONURL, REGISTRY_COLLECTION, AAS_COLLECTION, SUBMODEL_COLLECTION };
+		loadFromEnvironmentVariables(ENV_PREFIX, properties);
+	}
+
+	public void loadFromDefaultSource() {
+		loadFileOrDefaultResource(DEFAULT_FILE_KEY, DEFAULT_CONFIG_PATH);
+		loadFromEnvironmentVariables();
+	}
+
+	public String getDatabase() {
+		return getProperty(DATABASE);
+	}
+
+	public void setDatabase(String database) {
+		setProperty(DATABASE, database);
+	}
+
+	public String getConnectionUrl() {
+		return getProperty(CONNECTIONURL);
+	}
+
+	public void setConnectionUrl(String connectionUrl) {
+		setProperty(CONNECTIONURL, connectionUrl);
+	}
+
+	public String getRegistryCollection() {
+		return getProperty(REGISTRY_COLLECTION);
+	}
+
+	public void setRegistryCollection(String registryCollection) {
+		setProperty(REGISTRY_COLLECTION, registryCollection);
+	}
+
+	public String getAASCollection() {
+		return getProperty(AAS_COLLECTION);
+	}
+
+	public void setAASCollection(String aasCollection) {
+		setProperty(AAS_COLLECTION, aasCollection);
+	}
+
+	public String getSubmodelCollection() {
+		return getProperty(SUBMODEL_COLLECTION);
+	}
+
+	public void setSubmodelCollection(String submodelCollection) {
+		setProperty(SUBMODEL_COLLECTION, submodelCollection);
+	}
+}
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/BaSyxMqttConfiguration.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/BaSyxMqttConfiguration.java
new file mode 100644
index 0000000..08b7277
--- /dev/null
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/BaSyxMqttConfiguration.java
@@ -0,0 +1,168 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.components.configuration;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+
+/**
+ * Represents a BaSyx mqtt configuration for an mqtt connection.
+ * 
+ * @author espen
+ *
+ */
+public class BaSyxMqttConfiguration extends BaSyxConfiguration {
+	// Prefix for environment variables
+	public static final String ENV_PREFIX = "BaSyxMQTT_";
+
+	// Default BaSyx MQTT configuration
+	public static final String DEFAULT_USER = "";
+	public static final String DEFAULT_PASS = "";
+	public static final String DEFAULT_SERVER = "http://localhost:1883/";
+	public static final String DEFAULT_QOS = "1";
+
+	public static final String USER = "user";
+	public static final String PASS = "pass";
+	public static final String SERVER = "server";
+	public static final String QOS = "qos";
+	public static final String WHITELIST_PREFIX = "whitelist.";
+	public static final String WHITELIST_ELEMENT_PREFIX = "whitelist.element.";
+
+	// The default path for the context properties file
+	public static final String DEFAULT_CONFIG_PATH = "mqtt.properties";
+
+	// The default key for variables pointing to the configuration file
+	public static final String DEFAULT_FILE_KEY = "BASYX_MQTT";
+
+	public static Map<String, String> getDefaultProperties() {
+		Map<String, String> defaultProps = new HashMap<>();
+		defaultProps.put(USER, DEFAULT_USER);
+		defaultProps.put(PASS, DEFAULT_PASS);
+		defaultProps.put(SERVER, DEFAULT_SERVER);
+		defaultProps.put(QOS, DEFAULT_QOS);
+
+		return defaultProps;
+	}
+
+	/**
+	 * Constructor with predefined value map
+	 */
+	public BaSyxMqttConfiguration(Map<String, String> values) {
+		super(values);
+	}
+
+	/**
+	 * Empty Constructor - use default values
+	 */
+	public BaSyxMqttConfiguration() {
+		super(getDefaultProperties());
+	}
+
+	/**
+	 * Constructor with initial configuration
+	 * 
+	 * @param user   Username for MQTT connection
+	 * @param pass   Password for MQTT connection
+	 * @param server MQTT broker address
+	 * @param qos    MQTT quality of service level
+	 */
+	public BaSyxMqttConfiguration(String user, String pass, String server, int qos) {
+		this();
+		setUser(user);
+		setPass(pass);
+		setServer(server);
+		setQoS(qos);
+	}
+
+	/**
+	 * Load all settings except of the whitelist config part
+	 */
+	public void loadFromEnvironmentVariables() {
+		String[] properties = { USER, PASS, SERVER, QOS };
+		loadFromEnvironmentVariables(ENV_PREFIX, properties);
+	}
+
+	public void loadFromDefaultSource() {
+		loadFileOrDefaultResource(DEFAULT_FILE_KEY, DEFAULT_CONFIG_PATH);
+		loadFromEnvironmentVariables();
+	}
+
+	public String getUser() {
+		return getProperty(USER);
+	}
+
+	public void setUser(String user) {
+		setProperty(USER, user);
+	}
+
+	public String getPass() {
+		return getProperty(PASS);
+	}
+
+	public void setPass(String pass) {
+		setProperty(PASS, pass);
+	}
+
+	public String getServer() {
+		return getProperty(SERVER);
+	}
+
+	public void setServer(String server) {
+		setProperty(SERVER, server);
+	}
+
+	public int getQoS() {
+		return Integer.parseInt(getProperty(QOS));
+	}
+
+	public void setQoS(int qos) {
+		setProperty(QOS, Integer.toString(qos));
+	}
+
+	public boolean isWhitelistEnabled(String submodelId) {
+		return "true".equals(getProperty(WHITELIST_PREFIX + submodelId));
+	}
+
+	public void setWhitelistEnabled(String submodelId, boolean enabled) {
+		String propertyName = WHITELIST_PREFIX + submodelId;
+		if (enabled) {
+			setProperty(propertyName, "true");
+		} else {
+			setProperty(propertyName, "false");
+		}
+	}
+
+	public Set<String> getWhitelist(String submodelId) {
+		Set<String> whitelist = new HashSet<>();
+		String fullPrefix = WHITELIST_ELEMENT_PREFIX + submodelId;
+		List<String> properties = getProperties(fullPrefix);
+		
+		for ( String prop : properties ) {
+			if ( getProperty(prop).equals("true") ) {
+				// Removes submodel prefix (+ one separator) => whitelist.elements.smid.
+				String elementId = prop.substring(fullPrefix.length() + 1);
+				whitelist.add(elementId);
+			}
+		}
+		return whitelist;
+	}
+
+	public void setWhitelist(String submodelId, List<String> elementIds) {
+		String smPrefix = WHITELIST_ELEMENT_PREFIX + submodelId;
+		for (String elemId : elementIds) {
+			String propName = smPrefix + "." + elemId;
+			setProperty(propName, "true");
+		}
+	}
+}
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/BaSyxSQLConfiguration.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/BaSyxSQLConfiguration.java
index 1b31a36..9702570 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/BaSyxSQLConfiguration.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/BaSyxSQLConfiguration.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.components.configuration;
 
 import java.util.HashMap;
@@ -10,58 +19,118 @@
  *
  */
 public class BaSyxSQLConfiguration extends BaSyxConfiguration {
-	// Default BaSyx SQL configuration
-	private static final String DEFAULT_USER = "postgres";
-	private static final String DEFAULT_PASS = "admin";
-	private static final String DEFAULT_PATH = "//localhost/basyx-directory?";
-	private static final String DEFAULT_DRV = "org.postgresql.Driver";
-	private static final String DEFAULT_PREFIX = "jdbc:postgresql:";
+	// Prefix for environment variables
+	public static final String ENV_PREFIX = "BaSyxSQL_";
 
-	private static final String USER = "dbuser";
-	private static final String PASS = "dbpass";
-	private static final String PATH = "dburl";
-	private static final String DRV = "sqlDriver";
-	private static final String PREFIX = "sqlPrefix";
+	// Default BaSyx SQL configuration
+	public static final String DEFAULT_USER = "postgres";
+	public static final String DEFAULT_PASS = "admin";
+	public static final String DEFAULT_PATH = "//localhost/basyx-directory?";
+	public static final String DEFAULT_DRV = "org.postgresql.Driver";
+	public static final String DEFAULT_PREFIX = "jdbc:postgresql:";
+
+	public static final String USER = "dbuser";
+	public static final String PASS = "dbpass";
+	public static final String PATH = "dburl";
+	public static final String DRIVER = "sqlDriver";
+	public static final String PREFIX = "sqlPrefix";
 
 	// The default path for the context properties file
 	public static final String DEFAULT_CONFIG_PATH = "sql.properties";
 
+	// The default key for variables pointing to the configuration file
+	public static final String DEFAULT_FILE_KEY = "BASYX_SQL";
+
 	public static Map<String, String> getDefaultProperties() {
 		Map<String, String> defaultProps = new HashMap<>();
 		defaultProps.put(USER, DEFAULT_USER);
 		defaultProps.put(PASS, DEFAULT_PASS);
 		defaultProps.put(PATH, DEFAULT_PATH);
-		defaultProps.put(DRV, DEFAULT_DRV);
+		defaultProps.put(DRIVER, DEFAULT_DRV);
 		defaultProps.put(PREFIX, DEFAULT_PREFIX);
 
 		return defaultProps;
 	}
 
+	/**
+	 * Constructor with predefined value map
+	 */
 	public BaSyxSQLConfiguration(Map<String, String> values) {
 		super(values);
 	}
 
+	/**
+	 * Empty Constructor - use default values
+	 */
 	public BaSyxSQLConfiguration() {
 		super(getDefaultProperties());
 	}
 
+	/**
+	 * Constructor with initial configuration
+	 * 
+	 * @param user   Username for SQL database
+	 * @param pass   Password for SQL database
+	 * @param path   SQL connection path
+	 * @param driver SQL driver
+	 * @param prefix SQL driver prefix
+	 */
+	public BaSyxSQLConfiguration(String user, String pass, String path, String driver, String prefix) {
+		this();
+		setUser(user);
+		setPass(pass);
+		setPath(path);
+		setDriver(driver);
+		setPrefix(prefix);
+	}
+
+	public void loadFromEnvironmentVariables() {
+		String[] properties = { USER, PASS, PATH, DRIVER, PREFIX };
+		loadFromEnvironmentVariables(ENV_PREFIX, properties);
+	}
+
+	public void loadFromDefaultSource() {
+		loadFileOrDefaultResource(DEFAULT_FILE_KEY, DEFAULT_CONFIG_PATH);
+		loadFromEnvironmentVariables();
+	}
+
 	public String getUser() {
 		return getProperty(USER);
 	}
 
+	public void setUser(String user) {
+		setProperty(USER, user);
+	}
+
 	public String getPass() {
 		return getProperty(PASS);
 	}
 
+	public void setPass(String pass) {
+		setProperty(PASS, pass);
+	}
+
 	public String getPath() {
 		return getProperty(PATH);
 	}
 
-	public String getDrv() {
-		return getProperty(DRV);
+	public void setPath(String path) {
+		setProperty(PATH, path);
+	}
+
+	public String getDriver() {
+		return getProperty(DRIVER);
+	}
+
+	public void setDriver(String driver) {
+		setProperty(DRIVER, driver);
 	}
 
 	public String getPrefix() {
 		return getProperty(PREFIX);
 	}
+
+	public void setPrefix(String prefix) {
+		setProperty(PREFIX, prefix);
+	}
 }
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/CFGBaSyxConnection.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/CFGBaSyxConnection.java
index 1cb7301..1c46007 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/CFGBaSyxConnection.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/CFGBaSyxConnection.java
@@ -1,7 +1,16 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.components.configuration;
 
-import org.eclipse.basyx.vab.directory.api.IVABDirectoryService;
-import org.eclipse.basyx.vab.protocol.api.IConnectorProvider;
+import org.eclipse.basyx.vab.protocol.api.IConnectorFactory;
+import org.eclipse.basyx.vab.registry.api.IVABRegistryService;
 
 
 
@@ -69,7 +78,7 @@
 	/**
 	 * Create protocol provider
 	 */
-	public IConnectorProvider createConnectorProvider() {
+	public IConnectorFactory createConnectorProvider() {
 		// Create connector provider instance
 		return protocol.createInstance();
 	}
@@ -78,14 +87,14 @@
 	/**
 	 * Instantiate the directory class
 	 */
-	public IVABDirectoryService createDirectoryInstance() {
+	public IVABRegistryService createDirectoryInstance() {
 		// Try to create instance
 		try {
 			// Get Java class by name
 			Class<?> clazz = Class.forName(directoryProviderName);
 		
 			// Instantiate class
-			IVABDirectoryService directoryService = (IVABDirectoryService) clazz.newInstance();
+			IVABRegistryService directoryService = (IVABRegistryService) clazz.newInstance();
 			
 			// Return directory service instance
 			return directoryService;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/CFGBaSyxProtocolType.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/CFGBaSyxProtocolType.java
index c3b5fda..6e6b414 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/CFGBaSyxProtocolType.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/CFGBaSyxProtocolType.java
@@ -1,8 +1,17 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.components.configuration;
 
-import org.eclipse.basyx.vab.protocol.api.IConnectorProvider;
-import org.eclipse.basyx.vab.protocol.basyx.connector.BaSyxConnectorProvider;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
+import org.eclipse.basyx.vab.protocol.api.IConnectorFactory;
+import org.eclipse.basyx.vab.protocol.basyx.connector.BaSyxConnectorFactory;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorFactory;
 
 
 
@@ -44,10 +53,10 @@
 	/**
 	 * Create protocol instance
 	 */
-	public IConnectorProvider createInstance() {
+	public IConnectorFactory createInstance() {
 		// Create protocol instance
-		if (this.equals(HTTP))  return new HTTPConnectorProvider();
-		if (this.equals(BASYX)) return new BaSyxConnectorProvider();
+		if (this.equals(HTTP))  return new HTTPConnectorFactory();
+		if (this.equals(BASYX)) return new BaSyxConnectorFactory();
 		
 		// Unknown protocol
 		return null;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/ConfigurableComponent.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/ConfigurableComponent.java
index 856404d..4afde6f 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/ConfigurableComponent.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/ConfigurableComponent.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.components.configuration;
 
 import org.eclipse.basyx.components.configuration.builder.BaSyxConfigurationBuilder;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/ConfigurableProperty.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/ConfigurableProperty.java
index d21d8e3..17979f8 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/ConfigurableProperty.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/ConfigurableProperty.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.components.configuration;
 
 
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/builder/BaSyxConfigurationBuilder.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/builder/BaSyxConfigurationBuilder.java
index 3438b88..60e35fa 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/builder/BaSyxConfigurationBuilder.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/builder/BaSyxConfigurationBuilder.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.components.configuration.builder;
 
 import org.eclipse.basyx.components.configuration.ConfigurableComponent;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/builder/BaSyxDeviceManagerConfigurationBuilder.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/builder/BaSyxDeviceManagerConfigurationBuilder.java
index 0f878ab..7e643f4 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/builder/BaSyxDeviceManagerConfigurationBuilder.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/builder/BaSyxDeviceManagerConfigurationBuilder.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.components.configuration.builder;
 
 import org.eclipse.basyx.components.configuration.ConfigurableComponent;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/builder/BaSyxServiceConfigurationBuilder.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/builder/BaSyxServiceConfigurationBuilder.java
index aad6f59..96e438f 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/builder/BaSyxServiceConfigurationBuilder.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/builder/BaSyxServiceConfigurationBuilder.java
@@ -1,13 +1,22 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.components.configuration.builder;
 
 import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
-import org.eclipse.basyx.aas.registration.api.IAASRegistryService;
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
 import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
 import org.eclipse.basyx.components.configuration.CFGBaSyxProtocolType;
 import org.eclipse.basyx.components.configuration.ConfigurableComponent;
-import org.eclipse.basyx.vab.directory.api.IVABDirectoryService;
 import org.eclipse.basyx.vab.manager.VABConnectionManager;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorFactory;
+import org.eclipse.basyx.vab.registry.api.IVABRegistryService;
 
 /**
  * Configuration builder for BaSyx services
@@ -29,7 +38,7 @@
 	 */
 	protected CFGBaSyxProtocolType protocoltype = null;
 	
-	protected IVABDirectoryService vabDirectory = null;
+	protected IVABRegistryService vabDirectory = null;
 	
 	
 	/**
@@ -58,7 +67,7 @@
 	/**
 	 * Create registry instance based on configuration
 	 */
-	public IAASRegistryService getRegistry() {
+	public IAASRegistry getRegistry() {
 		// Create and return registry
 		return new AASRegistryProxy(registryURL);
 	}
@@ -81,7 +90,7 @@
 	 * Set VAB Directory
 	 */
 	@SuppressWarnings("unchecked")
-	public T directoryService(IVABDirectoryService vabDirectory) {
+	public T directoryService(IVABRegistryService vabDirectory) {
 		// Store VAB directory
 		this.vabDirectory = vabDirectory;
 
@@ -94,7 +103,7 @@
 	 */
 	public VABConnectionManager getConnectionManager() {
 		// Create and return VABConnectionManager
-		return new VABConnectionManager(vabDirectory, new HTTPConnectorProvider());
+		return new VABConnectionManager(vabDirectory, new HTTPConnectorFactory());
 	}
 
 	/**
@@ -102,7 +111,7 @@
 	 */
 	public ConnectedAssetAdministrationShellManager getConnetedAASManager() {
 		// Create and return connected AAS-manager
-		return new ConnectedAssetAdministrationShellManager(getRegistry(), new HTTPConnectorProvider());
+		return new ConnectedAssetAdministrationShellManager(getRegistry(), new HTTPConnectorFactory());
 	}
 }
 
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/exception/InsufficientConfigurationDataException.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/exception/InsufficientConfigurationDataException.java
index 49dbaec..22e73e4 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/exception/InsufficientConfigurationDataException.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/exception/InsufficientConfigurationDataException.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.components.configuration.exception;
 
 
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/device/BaseDevice.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/device/BaseDevice.java
index a975fa6..9927759 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/device/BaseDevice.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/device/BaseDevice.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.components.device;
 
 import org.eclipse.basyx.components.service.BaseBaSyxService;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/device/BaseSmartDevice.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/device/BaseSmartDevice.java
index 475e0b1..aa06d5f 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/device/BaseSmartDevice.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/device/BaseSmartDevice.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.components.device;
 
 import org.eclipse.basyx.models.controlcomponent.ControlComponent;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/device/BaseTCPControllableDeviceAdapter.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/device/BaseTCPControllableDeviceAdapter.java
index 37fee53..4ab2335 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/device/BaseTCPControllableDeviceAdapter.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/device/BaseTCPControllableDeviceAdapter.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.components.device;
 
 import org.eclipse.basyx.components.netcomm.NetworkReceiver;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/device/BaseTCPDeviceAdapter.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/device/BaseTCPDeviceAdapter.java
index 354f885..3055c75 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/device/BaseTCPDeviceAdapter.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/device/BaseTCPDeviceAdapter.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.components.device;
 
 import org.eclipse.basyx.components.netcomm.TCPClient;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/device/IBaSysNativeDeviceStatus.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/device/IBaSysNativeDeviceStatus.java
index a5a8f1b..3734c51 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/device/IBaSysNativeDeviceStatus.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/device/IBaSysNativeDeviceStatus.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.components.device;
 
 
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/devicemanager/DeviceManagerComponent.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/devicemanager/DeviceManagerComponent.java
index 4695058..040e0b1 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/devicemanager/DeviceManagerComponent.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/devicemanager/DeviceManagerComponent.java
@@ -1,5 +1,15 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.components.devicemanager;
 
+import org.eclipse.basyx.aas.aggregator.restapi.AASAggregatorProvider;
 import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
 import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
 import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
@@ -77,7 +87,7 @@
 	 * Returns the actual endpoint of the AAS managed by this component
 	 */
 	protected String getAASEndpoint(ModelUrn aasURN) {
-		return VABPathTools.concatenatePaths(getAASServerURL(), "/aas", aasURN.getEncodedURN());
+		return VABPathTools.concatenatePaths(getAASServerURL(), AASAggregatorProvider.PREFIX, aasURN.getEncodedURN(), "/aas");
 	}
 	
 	/**
@@ -88,9 +98,9 @@
 	 * 
 	 * @return Sub model descriptor endpoint points to default AAS server location and contains default prefix path
 	 */
-	protected SubmodelDescriptor addSubModelDescriptorURI(AASDescriptor aasDescriptor, ModelUrn subModelURN, String subModelId) {
+	protected SubmodelDescriptor addSubmodelDescriptorURI(AASDescriptor aasDescriptor, ModelUrn subModelURN, String subModelId) {
 		// Create sub model descriptor
-		String submodelEndpoint = VABPathTools.concatenatePaths(getAASServerURL(), "/aas/submodels", subModelId);
+		String submodelEndpoint = VABPathTools.concatenatePaths(getAASServerURL(), AASAggregatorProvider.PREFIX, VABPathTools.encodePathElement(aasDescriptor.getIdentifier().getId()), "/aas/submodels", subModelId);
 		SubmodelDescriptor submodelDescriptor = new SubmodelDescriptor(subModelId, subModelURN, submodelEndpoint);
 		
 		// Add sub model descriptor to AAS descriptor
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/devicemanager/TCPControllableDeviceManagerComponent.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/devicemanager/TCPControllableDeviceManagerComponent.java
index 9fc63d5..aa2cc3c 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/devicemanager/TCPControllableDeviceManagerComponent.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/devicemanager/TCPControllableDeviceManagerComponent.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.components.devicemanager;
 
 import org.eclipse.basyx.components.netcomm.NetworkReceiver;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/devicemanager/TCPDeviceManagerComponent.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/devicemanager/TCPDeviceManagerComponent.java
index 8aa6fd8..3faa021 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/devicemanager/TCPDeviceManagerComponent.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/devicemanager/TCPDeviceManagerComponent.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.components.devicemanager;
 
 import org.eclipse.basyx.components.netcomm.NetworkReceiver;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/directory/AASDirectoryEntry.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/directory/AASDirectoryEntry.java
deleted file mode 100644
index 84589ef..0000000
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/directory/AASDirectoryEntry.java
+++ /dev/null
@@ -1,375 +0,0 @@
-package org.eclipse.basyx.components.directory;
-
-import java.util.Collection;
-import java.util.HashSet;
-
-import org.eclipse.basyx.components.directory.exception.AASDirectoryFormatException;
-
-
-
-/**
- * Asset Administration Shell or sub model directory entry
- * 
- * IDs usually are formed as URIs: urn:<legalBody>:<SubUnit>:<Submodel>:<version>:<revision>:<elementID>#<instance>
- * 
- * @author kuhn
- *
- */
-public class AASDirectoryEntry {
-
-	
-	/**
-	 * Indicate undefined AAS content type
-	 */
-	public static final int AAS_CONTENTTYPE_UNDEFINED = -1;
-
-	
-	/**
-	 * Indicate local AAS content type. The serialized AAS is stored in the content property of this class. 
-	 */
-	public static final int AAS_CONTENTTYPE_LOCAL = 1;
-
-	
-	/**
-	 * Indicate remote AAS content type. The content property of this class contains a URL that points to the directory service. 
-	 */
-	public static final int AAS_CONTENTTYPE_REMOTE = 2;
-
-	
-	/**
-	 * Indicate proxy AAS content type. The content property of this class contains an ID (specified as URI) that points to the
-	 * AAS entry that all requests should be forwarded to. 
-	 */
-	public static final int AAS_CONTENTTYPE_PROXY = 3;
-
-	
-	
-	
-	
-	/**
-	 * Store the AAS ID
-	 */
-	protected String id = null;
-	
-	
-	/**
-	 * Store the AAS content
-	 */
-	protected String content = null;
-	
-	
-	/**
-	 * Store the AAS content type (local, remote, or proxy)
-	 * 
-	 * Local AAS content means that the AAS is serialized in the content property. Remote indicates
-	 * that the content property contains a URL that points to the AAS. Proxy indicates that the
-	 * content contains another AAS ID, to which requests will be forwarded. 
-	 */
-	protected int contentType = -1;
-	
-	
-	/**
-	 * Store the tags for this AAS
-	 */
-	protected HashSet<String> tags = new HashSet<>();
-	
-	
-	
-	
-	
-	/**
-	 * Constructor
-	 */
-	public AASDirectoryEntry(String aasId, String aasContent, String aasContentType, String aasTags) {
-		// Store AAS parameter
-		id      = aasId;
-		content = aasContent;
-		
-		
-		// Try to process AAS content type
-		try {
-			// Store AAS content type
-			switch(aasContentType.toLowerCase()) {
-				case "local":  contentType = AAS_CONTENTTYPE_LOCAL; break;
-				case "remote": contentType = AAS_CONTENTTYPE_REMOTE; break;
-				case "proxy":  contentType = AAS_CONTENTTYPE_PROXY; break;
-
-				default: throw new AASDirectoryFormatException("Unknown content type: "+aasContentType);
-			}
-		} catch (NullPointerException e) {
-			// Assume local AAS for undefined AAS types
-			contentType = AAS_CONTENTTYPE_LOCAL;
-		}
-		
-		
-		// Try to Store AAS tags
-		try {
-			String[] splitTags = aasTags.split(",");
-			// - Only add non-empty tags
-			for (String tag: splitTags) if (tag.trim().length() > 0) tags.add(tag.trim());
-		} catch (NullPointerException e) {
-			// Accept AAS without tags
-		}		
-	}
-	
-	
-	/**
-	 * Check if ID is a valid URI. A valid URI starts with "urn:" prefix and defines at least a legal body.
-	 */
-	public boolean isValidID() {
-		return (id.startsWith("urn"));
-	}
-
-	
-	/**
-	 * Check if ID contains a legal entity
-	 */
-	public boolean hasLegalEntity() {
-		// Split ID by ':' token
-		String[] idParts = id.split(":");
-		
-		// Check if subunit is defined
-		if (idParts.length < 2) return false;
-		
-		// Check if any information is contained in subunit field
-		return (idParts[1].trim().length() > 0);
-	}
-
-	
-	/**
-	 * Return the legal entity of this AAS
-	 */
-	public String getLegalEntity() {
-		// Split ID by ':' token
-		String[] idParts = id.split(":");
-		
-		// Return legal Entity part
-		return idParts[1];
-	}
-	
-	
-	/**
-	 * Check if AAS legal entity is of type (ends with given suffix, e.g. ".fraunhofer.de")
-	 */
-	public boolean isLegalEntityOf(String suffix) {
-		return getLegalEntity().endsWith(suffix);
-	}
-	
-	
-	/**
-	 * Check if ID contains a subunit
-	 */
-	public boolean hasSubUnit() {
-		// Split ID by ':' token
-		String[] idParts = id.split(":");
-		
-		// Check if subunit is defined
-		if (idParts.length < 3) return false;
-		
-		// Check if any information is contained in subunit field
-		return (idParts[2].trim().length() > 0);
-	}
-	
-	
-	/**
-	 * Get the subunit of the ID field
-	 */
-	public String getSubUnit() {
-		// Split ID by ':' token
-		String[] idParts = id.split(":");
-		
-		// Check if subunit is defined
-		if (idParts.length < 3) return null;
-		
-		// Check if any information is contained in subunit field
-		return idParts[2].trim();
-	}
-
-	
-	/**
-	 * Check if ID contains a sub model
-	 */
-	public boolean hasSubModel() {
-		// Split ID by ':' token
-		String[] idParts = id.split(":");
-		
-		// Check if subunit is defined
-		if (idParts.length < 4) return false;
-		
-		// Check if any information is contained in subunit field
-		return (idParts[3].trim().length() > 0);
-	}
-	
-	
-	/**
-	 * Get the sub model of the ID field
-	 */
-	public String getSubModel() {
-		// Split ID by ':' token
-		String[] idParts = id.split(":");
-		
-		// Check if subunit is defined
-		if (idParts.length < 4) return null;
-		
-		// Check if any information is contained in subunit field
-		return idParts[3].trim();
-	}
-
-	
-	/**
-	 * Check if ID contains a version
-	 */
-	public boolean hasVersion() {
-		// Split ID by ':' token
-		String[] idParts = id.split(":");
-		
-		// Check if subunit is defined
-		if (idParts.length < 5) return false;
-		
-		// Check if any information is contained in subunit field
-		return (idParts[4].trim().length() > 0);
-	}
-
-	
-	/**
-	 * Get AAS version
-	 */
-	public String getVersion() {
-		// Split ID by ':' token
-		String[] idParts = id.split(":");
-		
-		// Check if subunit is defined
-		if (idParts.length < 5) return null;
-		
-		// Check if any information is contained in subunit field
-		return idParts[4].trim();
-	}
-
-	
-	/**
-	 * Check if ID contains a revision
-	 */
-	public boolean hasRevision() {
-		// Split ID by ':' token
-		String[] idParts = id.split(":");
-		
-		// Check if subunit is defined
-		if (idParts.length < 6) return false;
-		
-		// Check if any information is contained in subunit field
-		return (idParts[5].trim().length() > 0);
-	}
-
-	
-	/**
-	 * Get AAS revision
-	 */
-	public String getRevision() {
-		// Split ID by ':' token
-		String[] idParts = id.split(":");
-		
-		// Check if subunit is defined
-		if (idParts.length < 6) return null;
-		
-		// Check if any information is contained in subunit field
-		return idParts[5].trim();
-	}
-	
-	
-	/**
-	 * Check if ID contains an element ID
-	 */
-	public boolean hasElementID() {
-		// Split ID by ':' token
-		String[] idParts = id.split(":");
-		
-		// Check if subunit is defined
-		if (idParts.length < 7) return false;
-		
-		// Remove element instance if an instance is defined
-		if (idParts[6].indexOf('#') > -1) idParts[6]=idParts[6].substring(0, idParts[6].indexOf('#'));
-		// Check if any information is contained in subunit field
-		return (idParts[6].trim().length() > 0);
-	}
-
-	
-	/**
-	 * Get element ID
-	 */
-	public String getElementID() {
-		// Split ID by ':' token
-		String[] idParts = id.split(":");
-		
-		// Check if subunit is defined
-		if (idParts.length < 7) return null;
-		
-		// Remove element instance if an instance is defined
-		if (idParts[6].indexOf('#') > -1) idParts[6]=idParts[6].substring(0, idParts[6].indexOf('#'));
-		// Check if any information is contained in subunit field
-		return idParts[6].trim();
-	}
-
-	
-	/**
-	 * Check if ID contains an instance
-	 */
-	public boolean hasElementInstance() {
-		// Split ID by ':' token
-		String[] idParts = id.split(":");
-		
-		// Check if subunit is defined
-		if (idParts.length < 7) return false;
-		
-		// Remove element instance if an instance is defined
-		if (idParts[6].indexOf('#') > -1) idParts[6]=idParts[6].substring(idParts[6].indexOf('#'));
-		// Check if any information is contained in subunit field
-		return (idParts[6].trim().length() > 0);
-	}
-
-
-	/**
-	 * Get instance ID
-	 */
-	public String getElementInstance() {
-		// Catch all exceptions 
-		try {
-			// Split ID by ':' token
-			String[] idParts = id.split(":");
-
-			// Check if subunit is defined
-			if (idParts.length < 7) return null;
-
-			// Remove element instance if an instance is defined
-			if (idParts[6].indexOf('#') > -1) idParts[6]=idParts[6].substring(idParts[6].indexOf('#')+1);
-			
-			// Check if any information is contained in subunit field
-			return idParts[6].trim();
-		} catch (Exception e) {
-			return null;
-		}
-	}
-	
-	
-	/**
-	 * Get AAS content
-	 */
-	public String getAASContent() {
-		return content;
-	}
-	
-	
-	/**
-	 * Get AAS content type
-	 */
-	public int getAASContentType() {
-		return contentType;
-	}
-	
-	
-	/**
-	 * Get AAS tags
-	 */
-	public Collection<String> getAASTags() {
-		return tags;
-	}
-}
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/directory/exception/AASDirectoryFormatException.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/directory/exception/AASDirectoryFormatException.java
deleted file mode 100644
index 79aacf2..0000000
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/directory/exception/AASDirectoryFormatException.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package org.eclipse.basyx.components.directory.exception;
-
-
-
-
-/**
- * Indicate a problem with the AAS directory format
- * 
- * @author kuhn
- *
- */
-public class AASDirectoryFormatException extends RuntimeException {
-
-	
-	/**
-	 * Version number support for serialized instances
-	 */
-	private static final long serialVersionUID = 1L;
-
-	
-	/**
-	 * Error message
-	 */
-	protected String errorMessage = null;
-	
-	
-	
-	
-	/**
-	 * Constructor
-	 */
-	public AASDirectoryFormatException(String errorMsg) {
-		errorMessage = errorMsg;
-	}
-}
-
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/directory/exception/AASDirectoryProviderException.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/directory/exception/AASDirectoryProviderException.java
deleted file mode 100644
index 30edf58..0000000
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/directory/exception/AASDirectoryProviderException.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package org.eclipse.basyx.components.directory.exception;
-
-
-
-
-/**
- * Indicate a problem with the AAS directory provider
- * 
- * @author kuhn
- *
- */
-public class AASDirectoryProviderException extends RuntimeException {
-
-	
-	/**
-	 * Version number support for serialized instances
-	 */
-	private static final long serialVersionUID = 1L;
-
-	
-	/**
-	 * Error message
-	 */
-	protected String errorMessage = null;
-	
-	
-	
-	
-	/**
-	 * Constructor
-	 */
-	public AASDirectoryProviderException(String errorMsg) {
-		errorMessage = errorMsg;
-	}
-}
-
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/json/JSONAASBundleFactory.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/json/JSONAASBundleFactory.java
new file mode 100644
index 0000000..bd9ae1d
--- /dev/null
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/json/JSONAASBundleFactory.java
@@ -0,0 +1,145 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.components.json;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+
+import org.eclipse.basyx.aas.factory.json.JSONToMetamodelConverter;
+import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.map.parts.Asset;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.api.qualifier.IIdentifiable;
+import org.eclipse.basyx.submodel.metamodel.api.reference.IKey;
+import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.support.bundle.AASBundle;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Creates multiple {@link AASBundle} from a JSON containing several AAS and
+ * Submodels <br />
+ * TODO: ConceptDescriptions
+ * 
+ * @author espen
+ *
+ */
+public class JSONAASBundleFactory {
+	private static Logger logger = LoggerFactory.getLogger(JSONAASBundleFactory.class);
+
+	private String content;
+
+	/**
+	 * 
+	 * @param jsonContent
+	 *                    the content of the JSON
+	 */
+	public JSONAASBundleFactory(String jsonContent) {
+		this.content = jsonContent;
+	}
+
+	public JSONAASBundleFactory(Path jsonFile) throws IOException {
+		content = new String(Files.readAllBytes(jsonFile));
+	}
+
+	/**
+	 * Creates the set of {@link AASBundle} contained in the JSON string.
+	 * 
+	 * @return
+	 */
+	public Set<AASBundle> create() {
+		JSONToMetamodelConverter converter = new JSONToMetamodelConverter(content);
+
+		List<AssetAdministrationShell> shells = converter.parseAAS();
+		List<Submodel> submodels = converter.parseSubmodels();
+
+		List<Asset> assets = converter.parseAssets();
+
+		Set<AASBundle> bundles = new HashSet<>();
+
+		for (AssetAdministrationShell shell : shells) {
+			// Retrieve asset
+			try {
+				IReference assetRef = shell.getAssetReference();
+				Asset asset = getByReference(assetRef, assets);
+				shell.setAsset(asset);
+			} catch (ResourceNotFoundException e) {
+				logger.warn("Can't find asset with id " + shell.getAssetReference().getKeys().get(0).getValue() + " for AAS " + shell.getIdShort() + "; If the asset is not provided in another way, this is an error!");
+			}
+
+			// Retrieve submodels
+			Set<ISubmodel> currentSM = retrieveSubmodelsForAAS(submodels, shell);
+			bundles.add(new AASBundle(shell, currentSM));
+		}
+
+		return bundles;
+	}
+
+	/**
+	 * Retrieves the Submodels belonging to an AAS
+	 * 
+	 * @param submodels
+	 * @param shell
+	 * @return
+	 */
+	private Set<ISubmodel> retrieveSubmodelsForAAS(List<Submodel> submodels, AssetAdministrationShell shell) {
+		Set<ISubmodel> currentSM = new HashSet<>();
+
+		for (IReference submodelRef : shell.getSubmodelReferences()) {
+			try {
+				ISubmodel sm = getByReference(submodelRef, submodels);
+				currentSM.add(sm);
+				logger.debug("Found Submodel " + sm.getIdShort() + " for AAS " + shell.getIdShort());
+			} catch (ResourceNotFoundException e) {
+				// If there's no match, the submodel is assumed to be provided by different
+				// means, e.g. it is already being hosted
+				logger.warn("Could not find Submodel " + submodelRef.getKeys().get(0).getValue() + " for AAS " + shell.getIdShort() + "; If it is not hosted elsewhere this is an error!");
+			}
+		}
+		return currentSM;
+	}
+
+	/**
+	 * Retrieves an identifiable from a list of identifiable by its reference
+	 * 
+	 * @param submodelRef
+	 * @param identifiable
+	 * @return
+	 * @throws ResourceNotFoundException
+	 */
+	private <T extends IIdentifiable> T getByReference(IReference ref, List<T> identifiable) throws ResourceNotFoundException {
+		IKey lastKey = null;
+		// It may be that only one key fits to the Submodel contained in the XML
+		for (IKey key : ref.getKeys()) {
+			lastKey = key;
+			// There will only be a single submodel matching the identification at max
+			Optional<T> match = identifiable.stream().filter(s -> s.getIdentification().getId().equals(key.getValue())).findFirst();
+			if (match.isPresent()) {
+				return match.get();
+			}
+		}
+		if (lastKey == null) {
+			throw new ResourceNotFoundException("Could not resolve reference without keys");
+		} else {
+			throw new ResourceNotFoundException(
+					"Could not resolve reference with last key '" + lastKey.getValue() + "'");
+		}
+
+		// If no identifiable is found, indicate it by throwing an exception
+
+	}
+}
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/netcomm/NetworkReceiver.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/netcomm/NetworkReceiver.java
index aa2986f..59edcb7 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/netcomm/NetworkReceiver.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/netcomm/NetworkReceiver.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.components.netcomm;
 
 
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/netcomm/TCPClient.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/netcomm/TCPClient.java
index 4611f1d..3848ae9 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/netcomm/TCPClient.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/netcomm/TCPClient.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.components.netcomm;
 
 import java.io.IOException;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/netcomm/TCPCommunicator.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/netcomm/TCPCommunicator.java
index 59ce17c..b3780d0 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/netcomm/TCPCommunicator.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/netcomm/TCPCommunicator.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.components.netcomm;
 
 import java.io.IOException;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/netcomm/TCPServer.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/netcomm/TCPServer.java
index 9170bd6..b89d82b 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/netcomm/TCPServer.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/netcomm/TCPServer.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.components.netcomm;
 
 import java.io.IOException;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/processengine/connector/DeviceServiceDelegate.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/processengine/connector/DeviceServiceDelegate.java
index cb10cbb..d7ee47a 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/processengine/connector/DeviceServiceDelegate.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/processengine/connector/DeviceServiceDelegate.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.components.processengine.connector;
 
 
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/processengine/connector/DeviceServiceExecutor.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/processengine/connector/DeviceServiceExecutor.java
index c5dbbea..a249694 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/processengine/connector/DeviceServiceExecutor.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/processengine/connector/DeviceServiceExecutor.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.components.processengine.connector;
 
 import java.util.ArrayList;
@@ -5,7 +14,7 @@
 import java.util.Map;
 
 import org.eclipse.basyx.aas.manager.api.IAssetAdministrationShellManager;
-import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
 import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
 import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
 import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperation;
@@ -51,7 +60,7 @@
 			IIdentifier smId = new Identifier(IdentifierType.CUSTOM, submodelid);
 
 			// create the submodel of the corresponding aas
-			ISubModel serviceSubmodel = manager.retrieveSubModel(aasId, smId);
+			ISubmodel serviceSubmodel = manager.retrieveSubmodel(aasId, smId);
 
 			// navigate to the expected service 
 			Map<String, IOperation> operations = serviceSubmodel.getOperations();
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/processengine/connector/IDeviceServiceExecutor.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/processengine/connector/IDeviceServiceExecutor.java
index 20a5ee6..c2b0031 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/processengine/connector/IDeviceServiceExecutor.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/processengine/connector/IDeviceServiceExecutor.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.components.processengine.connector;
 
 import java.util.List;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/provider/BaseConfiguredProvider.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/provider/BaseConfiguredProvider.java
index ca5da6d..f2a418d 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/provider/BaseConfiguredProvider.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/provider/BaseConfiguredProvider.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.components.provider;
 
 import java.util.Collection;
@@ -9,7 +18,7 @@
 import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
 import org.eclipse.basyx.submodel.metamodel.facade.SubmodelFacadeCustomSemantics;
 import org.eclipse.basyx.submodel.metamodel.facade.SubmodelFacadeIRDISemantics;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
 import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
 import org.eclipse.basyx.submodel.metamodel.map.qualifier.AdministrativeInformation;
 import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasDataSpecification;
@@ -20,8 +29,8 @@
 import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
 import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.submodel.restapi.SubModelProvider;
-import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
+import org.eclipse.basyx.submodel.restapi.SubmodelProvider;
+import org.eclipse.basyx.submodel.restapi.MultiSubmodelElementProvider;
 import org.eclipse.basyx.submodel.restapi.vab.VABSubmodelAPI;
 import org.eclipse.basyx.vab.modelprovider.map.VABMapProvider;
 import org.slf4j.Logger;
@@ -34,7 +43,7 @@
  *
  */
 
-public class BaseConfiguredProvider extends SubModelProvider {
+public class BaseConfiguredProvider extends SubmodelProvider {
 	
 	/**
 	 * Initiates a logger using the current class
@@ -44,7 +53,7 @@
 	/**
 	 * This is a sub model
 	 */
-	protected SubModel submodelData = null;
+	protected Submodel submodelData = null;
 	
 	public static final String SUBMODELSEMANTICS = "submodelSemantics";
 	public static final String TYPE = "type";
@@ -61,12 +70,12 @@
 		super();
 
 		// Create sub model
-		submodelData = createSubModel(cfgValues);
+		submodelData = createSubmodel(cfgValues);
 
 		setSubmodel(submodelData);
 	}
 
-	protected void setSubmodel(SubModel sm) {
+	protected void setSubmodel(Submodel sm) {
 		setAPI(new VABSubmodelAPI(new VABMapProvider(sm)));
 	}
 
@@ -96,7 +105,7 @@
 	 */
 	protected Collection<String> getConfiguredProperties(Map<Object, Object> cfgValues) {
 		// Split property string
-		return splitString((String) cfgValues.get(SubmodelElementProvider.PROPERTIES));
+		return splitString((String) cfgValues.get(MultiSubmodelElementProvider.ELEMENTS));
 	}
 
 	/**
@@ -136,9 +145,9 @@
 	 * @param cfgValues
 	 *            Provider configuration
 	 */
-	protected SubModel createSubModel(Map<Object, Object> cfgValues) {
+	protected Submodel createSubmodel(Map<Object, Object> cfgValues) {
 		// Create sub model
-		SubModel submodel = null;
+		Submodel submodel = null;
 
 		// Try to load and convert configuration values. Keep value null if any error occurs
 		String basyx_submodelSemantics = null;
@@ -225,7 +234,7 @@
 
 		// If no sub model was created, create an empty one
 		if (submodel == null)
-			submodel = new SubModel();
+			submodel = new Submodel();
 
 		// Return sub model data
 		return submodel;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/service/BaseBaSyxService.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/service/BaseBaSyxService.java
index 7b7ea46..65e6bd5 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/service/BaseBaSyxService.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/service/BaseBaSyxService.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.components.service;
 
 import java.util.HashMap;
@@ -5,7 +14,7 @@
 
 import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
 import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
-import org.eclipse.basyx.aas.registration.api.IAASRegistryService;
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
 import org.eclipse.basyx.components.configuration.ConfigurableComponent;
 import org.eclipse.basyx.components.configuration.builder.BaSyxServiceConfigurationBuilder;
 import org.eclipse.basyx.vab.manager.VABConnectionManager;
@@ -55,7 +64,7 @@
 	/**
 	 * Registry proxy reference that will be used for registering sub models
 	 */
-	protected IAASRegistryService registryProxy = null;
+	protected IAASRegistry registryProxy = null;
 
 
 	
@@ -243,7 +252,7 @@
 	/**
 	 * Set AAS registry proxy
 	 */
-	protected void setRegistry(IAASRegistryService regProxy) {
+	protected void setRegistry(IAASRegistry regProxy) {
 		registryProxy = regProxy;
 	}
 
@@ -251,7 +260,7 @@
 	/**
 	 * Get AAS registry proxy reference
 	 */
-	protected IAASRegistryService getRegistry() {
+	protected IAASRegistry getRegistry() {
 		return registryProxy;
 	}
 }
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/aas/AASBundleServlet.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/aas/AASBundleServlet.java
deleted file mode 100644
index 3d7d21a..0000000
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/aas/AASBundleServlet.java
+++ /dev/null
@@ -1,77 +0,0 @@
-package org.eclipse.basyx.components.servlet.aas;
-
-import java.util.Collection;
-import java.util.Collections;
-
-import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
-import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
-import org.eclipse.basyx.aas.restapi.AASModelProvider;
-import org.eclipse.basyx.aas.restapi.MultiAASProvider;
-import org.eclipse.basyx.aas.restapi.VABMultiSubmodelProvider;
-import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
-import org.eclipse.basyx.submodel.restapi.SubModelProvider;
-import org.eclipse.basyx.support.bundle.AASBundle;
-import org.eclipse.basyx.vab.protocol.http.server.VABHTTPInterface;
-
-/**
- * Servlet providing multiple AAS based on a passed {@link AASBundle}
- * 
- * @author schnicke
- *
- */
-public class AASBundleServlet extends VABHTTPInterface<MultiAASProvider> {
-	private static final long serialVersionUID = 4441135540490088430L;
-
-	/**
-	 * Creates a servlet hosting the AAS and its submodels specified in the bundle
-	 * 
-	 * @param bundle
-	 */
-	public AASBundleServlet(AASBundle bundle) {
-		this(Collections.singleton(bundle));
-	}
-
-	/**
-	 * Creates a servlet hosting multiple AAS and their submodels as specified in
-	 * the bundle list
-	 * 
-	 * @param bundles
-	 */
-	public AASBundleServlet(Collection<AASBundle> bundles) {
-		super(new MultiAASProvider());
-
-		MultiAASProvider multiAASProvider = getModelProvider();
-
-		for (AASBundle bundle : bundles) {
-			multiAASProvider.addMultiSubmodelProvider(bundle.getAAS().getIdShort(), createMultiSubmodelProvider(bundle));
-		}
-	}
-
-	/**
-	 * Creates the MultiSubmodelProvider based on a single bundle
-	 * 
-	 * @param bundle
-	 * @return
-	 */
-	private VABMultiSubmodelProvider createMultiSubmodelProvider(AASBundle bundle) {
-		VABMultiSubmodelProvider provider = new VABMultiSubmodelProvider();
-		IAssetAdministrationShell shell = bundle.getAAS();
-
-		// Check for correct type
-		if (!(shell instanceof AssetAdministrationShell)) {
-			throw new RuntimeException("Only instances of AssetAdministrationShell are allowed here");
-		}
-
-		provider.setAssetAdministrationShell(new AASModelProvider((AssetAdministrationShell) shell));
-		for (ISubModel sm : bundle.getSubmodels()) {
-
-			if (!(sm instanceof SubModel)) {
-				throw new RuntimeException("Only instances of SubModel are allowed here");
-			}
-
-			provider.addSubmodel(sm.getIdShort(), new SubModelProvider((SubModel) sm));
-		}
-		return provider;
-	}
-}
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/aas/AASServlet.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/aas/AASServlet.java
index e8a2194..2758fc9 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/aas/AASServlet.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/aas/AASServlet.java
@@ -1,8 +1,17 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.components.servlet.aas;
 
 import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
 import org.eclipse.basyx.aas.restapi.AASModelProvider;
-import org.eclipse.basyx.aas.restapi.VABMultiSubmodelProvider;
+import org.eclipse.basyx.aas.restapi.MultiSubmodelProvider;
 import org.eclipse.basyx.vab.protocol.http.server.VABHTTPInterface;
 
 /**
@@ -11,7 +20,7 @@
  * @author kuhn
  *
  */
-public class AASServlet extends VABHTTPInterface<VABMultiSubmodelProvider> {
+public class AASServlet extends VABHTTPInterface<MultiSubmodelProvider> {
 
 	/**
 	 * ID of serialized instances
@@ -22,7 +31,7 @@
 	 * Default constructor - based on a VABMultiSubmodelProvider
 	 */
 	public AASServlet() {
-		super(new VABMultiSubmodelProvider());
+		super(new MultiSubmodelProvider());
 	}
 
 	/**
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/registry/StaticCFGDirectoryServlet.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/registry/StaticCFGDirectoryServlet.java
deleted file mode 100644
index 57d0cbf..0000000
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/registry/StaticCFGDirectoryServlet.java
+++ /dev/null
@@ -1,454 +0,0 @@
-package org.eclipse.basyx.components.servlet.registry;
-
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URLDecoder;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.eclipse.basyx.components.directory.AASDirectoryEntry;
-import org.eclipse.basyx.components.directory.exception.AASDirectoryProviderException;
-import org.eclipse.basyx.vab.protocol.http.server.BasysHTTPServlet;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-
-
-
-/**
- * Static configuration file based directory provider
- * 
- * This directory provider provides a static directory. It therefore only supports get() operations. 
- * Modification of the directory via PUT/POST/PATCH/DELETE operations is not supported.
- * 
- * @author kuhn
- *
- */
-public class StaticCFGDirectoryServlet extends BasysHTTPServlet {
-	
-	/**
-	 * Initiates a logger using the current class
-	 */
-	private static final Logger logger = LoggerFactory.getLogger(StaticCFGDirectoryServlet.class);
-
-	
-	/**
-	 * Version information to identify the version of serialized instances
-	 */
-	private static final long serialVersionUID = 1L;
-
-	
-
-	/**
-	 * Configuration properties (raw input from file)
-	 */
-	protected Properties properties = null;
-	
-	
-	/**
-	 * Asset administration shells by ID
-	 */
-	protected Map<String, AASDirectoryEntry> aasByID = new HashMap<>();
-	
-	
-	/**
-	 * Asset administration shells by tag
-	 */
-	protected Map<String, Collection<AASDirectoryEntry>> aasByTag = new HashMap<>();
-	
-	
-	/**
-	 * Uplink server
-	 */
-	protected String uplink = null;
-	
-	
-	/**
-	 * Downlink servers
-	 */
-	protected Map<String, String> downlinks = new HashMap<>();
-	
-	
-	
-	
-	
-	/**
-	 * Constructor
-	 */
-	public StaticCFGDirectoryServlet() {
-		// Invoke base constructor
-		super();
-	}
-	
-	/**
-	 * Adds init parameter to servlet
-	 */
-	@Override
-	public String getInitParameter(String name) {
-
-		if (name.equals("config")) return "/WebContent/WEB-INF/config/directory/cfgdirectory/directory.properties";
-		
-		return null;
-	}
-	
-	/**
-	 * Load a property
-	 */
-	protected String extractProperty(Properties prop, String key) {
-		// Check if properties contain value
-		if (!prop.containsKey(key)) return null;
-		
-		// Extract and remove value
-		String value = (String) prop.get(key);
-		prop.remove(key);
-		
-		// Return value
-		return value;
-	}
-	
-	
-	
-	/**
-	 * Extract property keys with prefix and suffix. Prefix and suffix is removed from key.
-	 */
-	protected Collection<String> getProperties(Properties prop, String prefix, String suffix) {
-		// Store result
-		HashSet<String> result = new HashSet<>();
-		
-		// Iterate keys
-		for (String key: prop.stringPropertyNames()) {
-			if (key.startsWith(prefix) && key.endsWith(suffix)) result.add(key.substring(prefix.length(), key.length()-suffix.length()));
-		}
-		
-		// Return result
-		return result;
-	}
-	
-	
-	
-	/**
-	 * Extract downlink servers
-	 */
-	protected Map<String, String> extractDownlinks(Properties prop) {
-		// Return value
-		Map<String, String> result = new HashMap<>();
-		
-		// Downlink server names
-		Collection<String> downlinkServerNames = getProperties(prop, "cfg.downlink.", ".pattern");
-		
-		// Remove downlink pattern and server URL
-		for (String name: downlinkServerNames) {
-			// Get downlink pattern and server URL
-			result.put(prop.getProperty("cfg.downlink."+name+".pattern"), prop.getProperty("cfg.downlink."+name+".directory"));
-			// Remove pattern and directory properties
-			prop.remove("cfg.downlink."+name+".pattern");
-			prop.remove("cfg.downlink."+name+".directory");
-		}
-		
-		// Return downlink server mappings
-		return result;
-	}
-	
-	
-	
-	/**
-	 * Extract Asset Administration Shell definitions
-	 */
-	protected Map<String, AASDirectoryEntry> extractAAS(Properties prop) {
-		// Return value
-		Map<String, AASDirectoryEntry> result = new HashMap<>();
-		
-		// Get AAS IDs
-		Collection<String> aasIDs = getProperties(prop, "", ".id");
-		
-		// Create AAS directory entries from properties
-		for (String aasID : aasIDs) {
-			// Create AAS directory entry
-			AASDirectoryEntry entry = new AASDirectoryEntry(prop.getProperty(aasID+".id"), prop.getProperty(aasID+".aas"), prop.getProperty(aasID+".type"), prop.getProperty(aasID+".tags"));
-			
-			// Add AAS directory entry
-			result.put(prop.getProperty(aasID+".id"), entry);
-		}
-		
-		// Return ID to AAS mappings
-		return result;
-	}
-	
-	
-	
-	/**
-	 * Map AAS tags to AAS
-	 */
-	protected Map<String, Collection<AASDirectoryEntry>> mapAASToTags(Map<String, AASDirectoryEntry> aasByID) {
-		// Return value
-		Map<String, Collection<AASDirectoryEntry>> result = new HashMap<>();
-		
-		// Iterate AAS directory entries
-		for (AASDirectoryEntry dirEntry: aasByID.values()) {
-			// Process tags
-			for (String tag: dirEntry.getAASTags()) {
-				// Create tag if necessary
-				if (!result.containsKey(tag)) {result.put(tag, new HashSet<AASDirectoryEntry>());}
-				
-				// Add AAS to tag
-				result.get(tag).add(dirEntry);
-			}
-		}
-		
-		// Return HashTag to AAS mappings
-		return result;
-	}
-	
-	
-	
-	/**
-	 * Load properties from file
-	 */
-	protected void loadProperties(String cfgFilePath) {
-		// Read property file
-		try {
-			// Open property file
-			InputStream input = getServletContext().getResourceAsStream(cfgFilePath); 
-
-			// Instantiate property structure
-			properties = new Properties();
-			properties.load(input);
-			
-			logger.debug("properties:"+properties);
-			logger.debug("properties (keys):"+properties.keySet());
-			logger.debug("properties (cfg.downlink.is.pattern):"+properties.get("cfg.downlink.is.pattern"));
-			
-			// Process properties
-			// - Uplink server
-			uplink = extractProperty(properties, "cfg.uplink");
-			// - Downlink servers
-			downlinks = extractDownlinks(properties);
-			// - AAS by ID
-			aasByID = extractAAS(properties);
-			// - AAS by tag
-			aasByTag = mapAASToTags(aasByID);
-			
-			logger.debug("Downlink:"+downlinks);
-			logger.debug("properties:"+properties);
-			logger.debug("aasbyID:"+aasByID);
-			
-		} catch (IOException e) {
-			// Output exception
-			e.printStackTrace();
-		}		
-	}
-
-
-
-	/**
-	 * Initialize servlet
-	 * 
-	 * @throws ServletException 
-	 */
-	@Override
-	public void init() throws ServletException {
-		// Call base implementation
-		super.init();
-		
-		// Read configuration values
-		String configFilePath = getInitParameter("config");
-		// - Read property file
-		loadProperties(configFilePath);
-	}
-	
-	
-	/**
-	 * Get AAS content from AASDirectoryEntry
-	 */
-	protected String getAASContent(AASDirectoryEntry directoryEntry) {
-		// Process directory entry
-		switch (directoryEntry.getAASContentType()) {
-
-			// Local content type
-			case AASDirectoryEntry.AAS_CONTENTTYPE_LOCAL:
-				return directoryEntry.getAASContent();
-
-			// Remote content type
-			case AASDirectoryEntry.AAS_CONTENTTYPE_REMOTE:
-				throw new AASDirectoryProviderException("Unsupported AAS content type");
-
-			// Proxy content type - content is ID of AAS that contains the information
-			case AASDirectoryEntry.AAS_CONTENTTYPE_PROXY:
-				return getAASContentByID(directoryEntry.getAASContent());
-
-			// Unknown content type
-			default:
-				throw new AASDirectoryProviderException("Unknown AAS content type");
-		}
-	}
-	
-	
-	
-	/**
-	 * Get requested tags as collection
-	 */
-	protected Collection<String> getTagsAsCollection(String tags) {
-		// Collection stores AAS tags
-		Collection<String> alltags = new HashSet<>();
-		
-		// Catch null pointer exceptions
-		try {
-			// Get AAS tags
-			String[] splitTags  = tags.split(",");
-
-			// Only add non-empty tags
-			for (String tag: splitTags) if (tag.trim().length() > 0) alltags.add(tag.trim());
-		} catch (NullPointerException e) {}
-
-		// Return all tags
-		return alltags;
-	}
-	
-	
-	
-	/**
-	 * Get a specific AAS content with ID
-	 */
-	protected String getAASContentByID(String aasID) {
-		// Extract requested AAS ID
-		AASDirectoryEntry aas = aasByID.get(aasID);
-		
-		// Null pointer check
-		if (aas == null)
-			return null;
-		
-		// Return result
-		return getAASContent(aas);
-	}
-	
-	
-	
-	
-	
-	/**
-	 * Implement "Get" operation 
-	 * 
-	 * Process HTTP get request - get sub model property value
-	 */
-	@Override
-	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
-		// Process request depending on the path and on parameter
-		String uri 			= req.getRequestURI();
-		String contextPath  = req.getContextPath();
-		String path 		= URLDecoder.decode(uri.substring(contextPath.length()+1).substring(req.getServletPath().length()), "UTF-8"); // plus 1 for "/"
-				
-		// Extract action parameter
-		Collection<String> alltags = getTagsAsCollection(req.getParameter("tags"));
-		
-		
-		// Setup HTML response header
-		resp.setContentType("application/json");
-		resp.setCharacterEncoding("UTF-8");
-
-		
-		// Process get request
-		// - Get all (local) AAS
-		if (path.equals("api/v1/registry")) {
-			// Extract AAS directory entries
-			Collection<AASDirectoryEntry> entries = null;
-
-			// Check if tags are to be processed
-			if (alltags.isEmpty()) {
-				// Get all tags
-				entries = aasByID.values();
-			} else {
-				// HashSet that holds all elements
-				Set<AASDirectoryEntry> taggedEntries = new HashSet<>();
-				
-				// Get tagged elements that have all requested tags
-				// - Get first requested tag
-				taggedEntries.addAll(aasByTag.get(alltags.iterator().next()));
-				// - Remove all directory entries that do not have all tags
-				for (String tag: alltags) taggedEntries.retainAll(aasByTag.get(tag));
-				// - Place remaining elements into entries collection
-				entries = taggedEntries;
-			}
-			
-			// Build response string
-			StringBuilder response = new StringBuilder();
-			for (AASDirectoryEntry entry: entries) response.append(getAASContent(entry));
-
-			// Write result
-			sendResponse(response.toString(), resp.getWriter());
-			// End processing
-			return;
-		}
-		// Get a specific AAS
-		else if (path.startsWith("api/v1/registry/")) {
-			logger.debug("Getting:"+path);
-			
-			// Get requested AAS with ID
-			String aas = getAASContentByID(path.substring(new String("api/v1/registry/").length()));
-			
-			// Write result
-			sendResponse(aas, resp.getWriter());
-			// End processing
-			return;
-		} else {
-			// Send null response for unknown path
-			sendResponse(null, resp.getWriter());
-			return;
-		}
-	}
-
-	
-	
-	/**
-	 * Implement "Put" operation
-	 */
-	@Override
-	protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
-		// Indicate an unsupported operation
-		resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, "Request not implemented for this service");
-	}
-
-
-	
-	/**
-	 * <pre>
-	 * Handle HTTP POST operation. Creates a new Property, Operation, Event, Submodel or AAS or invokes an operation.
-	 */
-	@Override
-	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
-		// Indicate an unsupported operation
-		resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, "Request not implemented for this service");
-	}
-
-
-	
-	/**
-	 * Handle a HTTP PATCH operation. Updates a map or collection respective to action string.
-	 * 
-	 */
-	@Override
-	protected void doPatch(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
-		// Indicate an unsupported operation
-		resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, "Request not implemented for this service");
-	}
-	 
-
-	
-	 /**
-	 * Implement "Delete" operation.  Deletes any resource under the given path.
-	 */
-	@Override
-	protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
-		// Indicate an unsupported operation
-		resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, "Request not implemented for this service");
-	}
-}
-
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/submodel/SQLSubModelProviderServlet.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/submodel/SQLSubModelProviderServlet.java
deleted file mode 100644
index 7de51c7..0000000
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/submodel/SQLSubModelProviderServlet.java
+++ /dev/null
@@ -1,79 +0,0 @@
-package org.eclipse.basyx.components.servlet.submodel;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Properties;
-
-import javax.servlet.ServletException;
-
-import org.eclipse.basyx.aas.restapi.VABMultiSubmodelProvider;
-import org.eclipse.basyx.components.provider.BaseConfiguredProvider;
-import org.eclipse.basyx.components.sqlprovider.SQLPreconfiguredSubModelProvider;
-import org.eclipse.basyx.vab.protocol.http.server.VABHTTPInterface;
-
-/**
- * Servlet interface for SQL sub model provider
- * 
- * @author kuhn
- *
- */
-public class SQLSubModelProviderServlet extends VABHTTPInterface<VABMultiSubmodelProvider> {
-
-	/**
-	 * Version information to identify the version of serialized instances
-	 */
-	private static final long serialVersionUID = 1L;
-
-	/**
-	 * Sub model ID
-	 */
-	protected String submodelID = null;
-
-	/**
-	 * Configuration properties
-	 */
-	protected Properties cfgProperties = null;
-
-	/**
-	 * Constructor
-	 */
-	public SQLSubModelProviderServlet() {
-		// Invoke base constructor
-		super(new VABMultiSubmodelProvider());
-	}
-
-	/**
-	 * Initialize servlet
-	 * 
-	 * @throws ServletException
-	 */
-	public void init() throws ServletException {
-		// Call base implementation
-		super.init();
-
-		// Read configuration values
-		String configFilePath = (String) getInitParameter("config");
-
-		// Read property file
-		try {
-			// Open property file
-			InputStream input = getServletContext().getResourceAsStream(configFilePath);
-
-			// Instantiate property structure
-			cfgProperties = new Properties();
-			cfgProperties.load(input);
-
-			// Extract sub model provider properties
-			this.submodelID = cfgProperties.getProperty(BaseConfiguredProvider.buildBasyxCfgName(BaseConfiguredProvider.SUBMODELID));
-
-		} catch (IOException e) {
-			// Output exception
-			e.printStackTrace();
-		}
-
-		// Instantiate and add sub model provider
-		SQLPreconfiguredSubModelProvider sqlSMProvider = new SQLPreconfiguredSubModelProvider(cfgProperties);
-		// - Add sub model provider
-		this.getModelProvider().addSubmodel(submodelID, sqlSMProvider);
-	}
-}
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/submodel/SubmodelServlet.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/submodel/SubmodelServlet.java
index a728dd3..6d790ac 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/submodel/SubmodelServlet.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/submodel/SubmodelServlet.java
@@ -1,7 +1,16 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.components.servlet.submodel;
 
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
-import org.eclipse.basyx.submodel.restapi.SubModelProvider;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.restapi.SubmodelProvider;
 import org.eclipse.basyx.vab.protocol.http.server.VABHTTPInterface;
 
 /**
@@ -10,7 +19,7 @@
  * @author kuhn
  *
  */
-public class SubmodelServlet extends VABHTTPInterface<SubModelProvider> {
+public class SubmodelServlet extends VABHTTPInterface<SubmodelProvider> {
 
 	/**
 	 * ID of serialized instances
@@ -22,14 +31,14 @@
 	 */
 	public SubmodelServlet() {
 		// Invoke base constructor
-		super(new SubModelProvider());
+		super(new SubmodelProvider());
 	}
 
 	/**
 	 * Constructor with a predefined submodel
 	 */
-	public SubmodelServlet(SubModel exportedModel) {
+	public SubmodelServlet(Submodel exportedModel) {
 		// Invoke base constructor
-		super(new SubModelProvider(exportedModel));
+		super(new SubmodelProvider(exportedModel));
 	}
 }
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/submodel/cfg/AbstractCFGSubModelProviderServlet.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/submodel/cfg/AbstractCFGSubModelProviderServlet.java
deleted file mode 100644
index c87d657..0000000
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/submodel/cfg/AbstractCFGSubModelProviderServlet.java
+++ /dev/null
@@ -1,113 +0,0 @@
-package org.eclipse.basyx.components.servlet.submodel.cfg;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Properties;
-
-import javax.servlet.ServletException;
-
-import org.eclipse.basyx.aas.restapi.VABMultiSubmodelProvider;
-import org.eclipse.basyx.submodel.restapi.SubModelProvider;
-import org.eclipse.basyx.vab.protocol.http.server.VABHTTPInterface;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Abstract super class for all config file using submodel provider servlets
- * 
- * @author schnicke
- *
- */
-public abstract class AbstractCFGSubModelProviderServlet extends VABHTTPInterface<VABMultiSubmodelProvider> {
-	
-	/**
-	 * Initiates a logger using the current class
-	 */
-	private static final Logger logger = LoggerFactory.getLogger(AbstractCFGSubModelProviderServlet.class);
-	
-	/**
-	 * Version information to identify the version of serialized instances
-	 */
-	private static final long serialVersionUID = 1L;
-
-	/**
-	 * Store ID of the sub model provided by this provider
-	 */
-	protected String submodelID = null;
-
-	/**
-	 * Configuration properties
-	 */
-	protected Properties properties = null;
-
-
-	/**
-	 * Standard constructor creating a servlet containing a new
-	 * VABMultiSubmodelProvider()
-	 */
-	public AbstractCFGSubModelProviderServlet() {
-		super(new VABMultiSubmodelProvider());
-	}
-
-	/**
-	 * Load properties from file
-	 */
-	protected void loadProperties(String cfgFilePath) {
-		// Read property file
-		try {
-			// Open property file
-			InputStream input = getServletContext().getResourceAsStream(cfgFilePath);
-
-			// Instantiate property structure
-			properties = new Properties();
-			properties.load(input);
-
-			// Extract AAS properties
-			this.submodelID = properties.getProperty(getSubmodelId());
-		} catch (IOException e) {
-			// Output exception
-			e.printStackTrace();
-		}
-	}
-
-	/**
-	 * Initialize servlet
-	 * 
-	 * @throws ServletException
-	 */
-	@Override
-	public void init() throws ServletException {
-		// Call base implementation
-		super.init();
-
-		// Read configuration values
-		String configFilePath = getInitParameter("config");
-		// - Read property file
-		loadProperties(configFilePath);
-		
-		logger.debug("1:" + submodelID);
-
-		// Create sub model provider
-		SubModelProvider submodelProvider = createProvider(properties);
-		// - Add sub model provider
-		this.getModelProvider().addSubmodel(submodelID, submodelProvider);
-
-		logger.debug("CFG file loaded");
-	}
-
-	/**
-	 * Retrieves the submodel id
-	 * 
-	 * @return
-	 */
-	protected abstract String getSubmodelId();
-
-	/**
-	 * Creates the appropriate provider based on the passed properties
-	 * 
-	 * @param properties
-	 * @return
-	 */
-	protected abstract SubModelProvider createProvider(Properties properties);
-
-}
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/submodel/cfg/CFGSubModelProviderServlet.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/submodel/cfg/CFGSubModelProviderServlet.java
deleted file mode 100644
index 1391f89..0000000
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/submodel/cfg/CFGSubModelProviderServlet.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package org.eclipse.basyx.components.servlet.submodel.cfg;
-
-import java.util.Properties;
-
-import org.eclipse.basyx.components.cfgprovider.CFGSubModelProvider;
-import org.eclipse.basyx.components.provider.BaseConfiguredProvider;
-import org.eclipse.basyx.submodel.restapi.SubModelProvider;
-
-/**
- * Servlet interface for configuration file sub model provider
- * 
- * @author kuhn
- *
- */
-public class CFGSubModelProviderServlet extends AbstractCFGSubModelProviderServlet {
-
-	/**
-	 * Version information to identify the version of serialized instances
-	 */
-	private static final long serialVersionUID = -7525848804623194574L;
-
-
-	@Override
-	protected String getSubmodelId() {
-		return BaseConfiguredProvider.buildBasyxCfgName(BaseConfiguredProvider.SUBMODELID);
-	}
-
-	@Override
-	protected SubModelProvider createProvider(Properties properties) {
-		return new CFGSubModelProvider(properties);
-	}
-}
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/submodel/cfg/RawCFGSubModelProviderServlet.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/submodel/cfg/RawCFGSubModelProviderServlet.java
deleted file mode 100644
index 9a87495..0000000
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/submodel/cfg/RawCFGSubModelProviderServlet.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package org.eclipse.basyx.components.servlet.submodel.cfg;
-
-import java.util.Properties;
-
-import org.eclipse.basyx.components.cfgprovider.RawCFGSubModelProvider;
-import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
-import org.eclipse.basyx.submodel.restapi.SubModelProvider;
-
-/**
- * Servlet interface for configuration file sub model provider
- * 
- * @author kuhn
- *
- */
-public class RawCFGSubModelProviderServlet extends AbstractCFGSubModelProviderServlet {
-
-	/**
-	 * Version information to identify the version of serialized instances
-	 */
-	private static final long serialVersionUID = -8132051635222485719L;
-
-
-	@Override
-	protected String getSubmodelId() {
-		return Referable.IDSHORT;
-	}
-
-
-	@Override
-	protected SubModelProvider createProvider(Properties properties) {
-		return new RawCFGSubModelProvider(properties);
-	}
-}
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/vab/VABLambdaServlet.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/vab/VABLambdaServlet.java
index fbd7e5d..1113c40 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/vab/VABLambdaServlet.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/vab/VABLambdaServlet.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.components.servlet.vab;
 
 import java.util.HashMap;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/SQLPreconfiguredSubModelProvider.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/SQLPreconfiguredSubModelProvider.java
deleted file mode 100644
index 43dc58e..0000000
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/SQLPreconfiguredSubModelProvider.java
+++ /dev/null
@@ -1,517 +0,0 @@
-package org.eclipse.basyx.components.sqlprovider;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
-
-import org.eclipse.basyx.components.provider.BaseConfiguredProvider;
-import org.eclipse.basyx.components.sqlprovider.driver.SQLDriver;
-import org.eclipse.basyx.components.sqlprovider.query.DynamicSQLQuery;
-import org.eclipse.basyx.components.sqlprovider.query.DynamicSQLRunner;
-import org.eclipse.basyx.components.sqlprovider.query.DynamicSQLUpdate;
-import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaHandler;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-
-
-
-/**
- * Asset administration shell sub model provider that connects to SQL database
- * 
- * @author kuhn
- *
- */
-public class SQLPreconfiguredSubModelProvider extends BaseConfiguredProvider {
-	
-	/**
-	 * Initiates a logger using the current class
-	 */
-	private static final Logger logger = LoggerFactory.getLogger(SQLPreconfiguredSubModelProvider.class);
-	
-	/**
-	 * SQL database user name
-	 */
-	protected String sqlUser = null;
-
-	/**
-	 * SQL database password
-	 */
-	protected String sqlPass = null;
-	
-	/**
-	 * SQL database path
-	 */
-	protected String sqlURL  = null;
-
-	
-	
-	/**
-	 * SQL database driver
-	 */
-	protected String sqlDriver = null;
-	
-	/**
-	 * SQL database query prefix
-	 */
-	protected String sqlPrefix = null;
-	
-	
-	
-	/**
-	 * SQL property connections
-	 */
-	protected Set<String> sqlPropertyConnections = new HashSet<>();
-	
-
-	/**
-	 * SQL operation connections
-	 */
-	protected Set<String> sqlOperationConnections = new HashSet<>();
-
-	
-	
-	/**
-	 * Run queries to access properties via 'get' operation
-	 */
-	protected Map<String, DynamicSQLRunner> propertyGetQueries = new HashMap<>();
-
-	
-	/**
-	 * Run SQL update to access properties via 'set' operation
-	 */
-	protected Map<String, DynamicSQLRunner> propertySetQueries = new HashMap<>();
-
-	
-	/**
-	 * Run SQL update to access properties via 'create' operation
-	 */
-	protected Map<String, DynamicSQLRunner> propertyCreateQueries = new HashMap<>();
-
-
-	/**
-	 * Run SQL update to access properties via 'delete' operation
-	 */
-	protected Map<String, DynamicSQLRunner> propertyDeleteQueries = new HashMap<>();
-
-
-	
-	/**
-	 * SQL operations
-	 */
-	protected Map<String, DynamicSQLRunner> operations = new HashMap<>();
-
-	
-	/**
-	 * SQL operations that run as update operations. Not contained operations are query operations.
-	 */
-	protected Set<String> updateOperations = new HashSet<>();
-	
-	/**
-	 * An SQL driver instance to connect to the database
-	 */
-	protected SQLDriver driver;
-
-	
-	public static final String DBUSER = "dbuser";
-	public static final String DBPASS = "dbpass";
-	public static final String DBURL = "dburl";
-	public static final String DRIVER = "driver";
-	public static final String PREFIX = "prefix";
-	public static final String PROPERTIES = "properties";
-	public static final String OPERATIONS = "operations";
-	
-	
-	/**
-	 * Constructor
-	 */
-	public SQLPreconfiguredSubModelProvider(Properties cfgValues) {
-		// Call base constructor
-		super(cfgValues);
-		
-		// Create sub model
-		submodelData = createSubModel(cfgValues);
-
-		// Load predefined elements from sub model
-		
-		try {
-			setModelPropertyValue("", submodelData);
-		} catch (Exception e) {
-			e.printStackTrace();
-		}
-
-		
-		// Extract SQL properties
-		sqlUser = cfgValues.getProperty(buildSqlCfgName(DBUSER));
-		sqlPass = cfgValues.getProperty(buildSqlCfgName(DBPASS));
-		sqlURL  = cfgValues.getProperty(buildSqlCfgName(DBURL));
-
-		// Extract SQL driver properties
-		sqlDriver = cfgValues.getProperty(buildSqlCfgName(DRIVER));
-		sqlPrefix = cfgValues.getProperty(buildSqlCfgName(PREFIX));
-		
-		// Create a SQL driver instance
-		driver = new SQLDriver(sqlURL, sqlUser, sqlPass, sqlPrefix, sqlDriver);
-		
-		// Load and parse SQL property and operation connections
-		sqlPropertyConnections.addAll(splitString(cfgValues.getProperty(buildSqlCfgName(PROPERTIES))));
-		sqlOperationConnections.addAll(splitString(cfgValues.getProperty(buildSqlCfgName(OPERATIONS))));
-
-		
-		
-		// Add properties
-		for (String propertyName: sqlPropertyConnections) createSQLProperty(propertyName, cfgValues);
-		
-		/*
-			// Try to parse parameter
-			propertyGetQueries.put(propertyName, createSQLOperation(propertyName+".get", cfgValues));
-			propertySetQueries.put(propertyName, createSQLOperation(propertyName+".set", cfgValues));
-			propertyCreateQueries.put(propertyName, createSQLOperation(propertyName+".create", cfgValues));
-			propertyDeleteQueries.put(propertyName, createSQLOperation(propertyName+".delete", cfgValues));
-			
-			
-			Map<String, Object> mapAccessors = VABLambdaProviderHelper.createMap((Supplier<?>) () -> {
-				return propertyMap_val;
-			}, (Consumer<Map<String, Object>>) (map) -> {
-				propertyMap_val = map;
-			}, (BiConsumer<String, Object>) (key, value) -> {
-				propertyMap_val.put(key, value);
-			}, (Consumer<Object>) (o) -> {
-				propertyMap_val.remove(o);
-			});
-
-		}*/
-		
-		
-		// Add operations
-		//for (String operationName: sqlOperationConnections) createSQLOperation(operationName, cfgValues); 
-		/*{
-			// Create operation
-			operations.put(operationName, createSQLOperation(operationName, cfgValues));
-			// Mark operation as update operation depending on operations/<operationName>_kind property value
-			try {
-				if (cfgValues.getProperty(operationName+"_kind").trim().equalsIgnoreCase("update")) {
-					updateOperations.add(operationName);
-				}
-			} catch (Exception e) {}
-		}*/
-	}
-	
-	
-	
-	/**
-	 * Create an SQL property
-	 */
-	protected void createSQLProperty(String name, Properties cfgValues) {
-		// Create Map with lambdas that hold SQL operations
-		Map<String, Object> value = new HashMap<>();
-		
-		// Get operation
-		{
-			// Get parameter
-			String queryString    = cfgValues.getProperty(name+".get");
-			String resultFilterOp = cfgValues.getProperty(name+".get.result");
-
-			// Trim query string and resultFilterOp (remove '"' at beginning and end)
-			queryString    = queryString.substring(1, queryString.length()-1);
-			try {resultFilterOp = resultFilterOp.substring(1, resultFilterOp.length()-1);} catch (NullPointerException | StringIndexOutOfBoundsException e) {}
-
-			// Create dynamic SQL query
-			value.put(VABLambdaHandler.VALUE_GET_SUFFIX, new DynamicSQLQuery(driver, queryString, resultFilterOp));
-		}
-		
-		// Set operation
-		{
-			// Get parameter
-			String updateString   = cfgValues.getProperty(name+".set");
-
-			// Trim query string and resultFilterOp (remove '"' at beginning and end)
-			updateString    = updateString.substring(1, updateString.length()-1);
-
-			// Create dynamic SQL query
-			value.put(VABLambdaHandler.VALUE_SET_SUFFIX, new DynamicSQLUpdate(driver, updateString));
-		}
-
-		// Delete operation
-		{
-			// Get parameter
-			String updateString   = cfgValues.getProperty(name+".delete");
-
-			// Trim query string and resultFilterOp (remove '"' at beginning and end)
-			updateString    = updateString.substring(1, updateString.length()-1);
-
-			// Create dynamic SQL query
-			value.put(VABLambdaHandler.VALUE_REMOVEKEY_SUFFIX, new DynamicSQLUpdate(driver, updateString));
-			value.put(VABLambdaHandler.VALUE_REMOVEOBJ_SUFFIX, new DynamicSQLUpdate(driver, updateString));
-		}
-		
-		// Create operation
-		{
-			// Get parameter
-			String updateString   = cfgValues.getProperty(name+".create");
-
-			// Trim query string and resultFilterOp (remove '"' at beginning and end)
-			updateString    = updateString.substring(1, updateString.length()-1);
-
-			// Create dynamic SQL query
-			value.put(VABLambdaHandler.VALUE_INSERT_SUFFIX, new DynamicSQLUpdate(driver, updateString));
-		}
-		
-		
-		logger.debug("Putting SQL:"+name);
-		// Add property as map of lambdas
-		submodelData.getProperties().put(name, createSubmodelElement(name, value, cfgValues));
-	}
-
-	
-	/**
-	 * Create a dynamic SQL operation
-	 */
-	protected DynamicSQLRunner createSQLOperation(String propertyName, Properties cfgValues) {/*
-		// Check parameter presence
-		if (!cfgValues.containsKey(propertyName)) return null;
-		
-		// Get parameter count and parameter count
-		int    parameterCount = Integer.parseInt(cfgValues.getProperty(propertyName+".parameter"));
-		String queryString    = cfgValues.getProperty(propertyName);
-		String resultFilterOp = cfgValues.getProperty(propertyName+".result");
-		
-		// Trim query string and resultFilterOp (remove '"' at beginning and end)
-		queryString    = queryString.substring(1, queryString.length()-1);
-		try {resultFilterOp = resultFilterOp.substring(1, resultFilterOp.length()-1);} catch (NullPointerException | StringIndexOutOfBoundsException e) {}
-		
-		// Create dynamic SQL query
-		DynamicSQLRunner sqlQuery = new DynamicSQLRunner(sqlURL, sqlUser, sqlPass, sqlPrefix, sqlDriver, parameterCount, queryString, resultFilterOp);
-
-		// Return created query
-		return sqlQuery;*/
-		
-		return null;
-	}
-	
-	
-	/**
-	 * Split a whitespace delimited string
-	 */
-	protected Collection<String> splitString(String input) {
-		// Return value
-		HashSet<String> result = new HashSet<>();
-		
-		// Split string into segments
-		for (String inputStr: input.split(" ")) result.add(inputStr.trim());
-		
-		// Return result
-		return result;
-	}
-	
-	
-	/**
-	 * Create a key list for an SQL statement
-	 *//*
-	protected String sqlCreateKeys(Collection<String> keys) {
-		// Return value builder
-		StringBuilder result = new StringBuilder();
-		
-		// Process keys
-		// - Flag that handles the first key
-		boolean isFirst = true;
-		// - Process keys
-		for (String key: keys) {if (!isFirst) result.append(","); else isFirst=false; result.append(key);}
-		
-		// Return string
-		return result.toString();
-	}*/
-	
-	
-	/**
-	 * Extract a list of values from a map
-	 *//*
-	protected String sqlCreateValues(Collection<Object> values) {
-		// Return value builder
-		StringBuilder result = new StringBuilder();
-		
-		// Process keys
-		// - Flag that handles the first key
-		boolean isFirst = true;
-		// - Process keys
-		for (Object key: values) {if (!isFirst) result.append(","); else isFirst=false; result.append("'"+key+"'");}
-		
-		// Return string
-		return result.toString();
-	}*/
-
-
-	
-	/**
-	 * Create (insert) a value into the SQL table
-	 *//*
-	@Override @SuppressWarnings("unchecked")
-	public void createValue(String propertyName, Object arg1) throws Exception {
-		// Set query
-		DynamicSQLRunner query = propertyCreateQueries.get(propertyName);
-		
-		// Null pointer check
-		if (query == null) return;
-		
-		// Create parameter array
-		Object[] parameter = new Object[2];
-		parameter[0] = sqlCreateKeys(((Map<String, Object>) arg1).keySet());
-		parameter[1] = sqlCreateValues(((Map<String, Object>) arg1).values());
-		
-		// Execute query and return result
-		query.runUpdate(parameter);
-	}*/
-
-
-	
-	/**
-	 * Delete a value from the SQL table
-	 *//*
-	@Override
-	public void deleteValue(String arg0) throws Exception {
-		// This is not implemented
-	}*/
-
-
-	
-	/**
-	 * Delete a value from the SQL table
-	 *//*
-	@Override @SuppressWarnings("unchecked")
-	public void deleteValue(String propertyName, Object arg1) throws Exception {
-		// Set query
-		DynamicSQLRunner query = propertyDeleteQueries.get(propertyName);
-		
-		// Null pointer check
-		if (query == null) return;
-
-		// Cast argument to collection
-		Collection<Object> parameterList = (Collection<Object>) arg1;
-		
-		// Create parameter array
-		Object[] parameter = new Object[parameterList.size()];
-		// - Copy parameter
-		int counter = 0; for (Object par: parameterList) parameter[counter++] = par;
-		
-		// Execute query and return result
-		query.runUpdate(parameter);
-	}*/
-
-	
-/*
-	@Override
-	public Map<String, IElementReference> getContainedElements(String arg0) {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
-
-	@Override
-	public String getElementScope(String arg0) {
-		logger.debug("GetScope:"+arg0);
-		// TODO Auto-generated method stub
-		return null;
-	}
-*/
-
-	
-	/**
-	 * Query the SQL database
-	 *//*
-	@Override
-	public Object getModelPropertyValue(String propertyName) {
-		// Get query
-		DynamicSQLRunner query = propertyGetQueries.get(propertyName);
-		
-		// Null pointer check
-		if (query == null) return null;
-		
-		// Execute query and return result
-		return query.runQuery();
-	}*/
-
-
-	
-	/**
-	 * Invoke operation with given parameter list
-	 *//*
-	@Override
-	public Object invokeOperation(String propertyName, Object[] parameter) throws Exception {
-		// Set query
-		DynamicSQLRunner query = operations.get(propertyName);
-		
-		// Null pointer check
-		if (query == null) return null;
-		
-		// Execute query and return result
-		if (updateOperations.contains(propertyName)) {
-			query.runUpdate(parameter); 
-			return null; 
-		} else {
-			return query.runQuery(parameter);
-		}
-	}*/
-
-
-	
-	/**
-	 * Invoke set operation with given parameter
-	 *//*
-	@Override @SuppressWarnings("unchecked")
-	public void setModelPropertyValue(String propertyName, Object arg1) throws Exception {
-		// Set query
-		DynamicSQLRunner query = propertySetQueries.get(propertyName);
-		
-		// Null pointer check
-		if (query == null) return;
-
-		logger.debug("LENC:"+arg1);
-
-		// Create parameter array
-		Object[] parameter = null;
-		// - Process collections
-		if (arg1 instanceof Collection) {
-			// Cast to collection
-			Collection<Object> parameterList = (Collection<Object>) arg1;
-			
-			// Create parameter array and copy parameter
-			parameter = new Object[parameterList.size()];
-			int counter = 0; for (Object par: parameterList) parameter[counter++] = par;
-		} else {
-			// Create parameter array and copy parameter
-			parameter = new Object[1];
-			parameter[0] = arg1;			
-		}
-		
-		
-		// Execute query and return result
-		query.runUpdate(parameter);
-	}*/
-
-
-	
-	/**
-	 * Invoke set operation with given parameter list
-	 *//*
-	@Override
-	public void setModelPropertyValue(String propertyName, Object... parameter) throws Exception {
-		// Set query
-		DynamicSQLRunner query = propertySetQueries.get(propertyName);
-		
-		// Null pointer check
-		if (query == null) return;
-		
-		logger.debug("LEN:"+parameter.length);
-		logger.debug("LEN-0:"+parameter[0]);
-
-		// Execute query and return result
-		query.runUpdate(parameter);
-	}*/
-	
-	public static String buildSqlCfgName(String valueName) {
-		return BaseConfiguredProvider.buildCfgName("basyx.sql", valueName);
-	}
-}
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/SQLProviderTestOLD.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/SQLProviderTestOLD.java
deleted file mode 100644
index 772b1ee..0000000
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/SQLProviderTestOLD.java
+++ /dev/null
@@ -1,186 +0,0 @@
-package org.eclipse.basyx.components.sqlprovider;
-
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.Collection;
-import java.util.LinkedList;
-
-import org.eclipse.basyx.components.sqlprovider.driver.ISQLDriver;
-import org.eclipse.basyx.components.sqlprovider.driver.SQLDriver;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class SQLProviderTestOLD {
-	
-	/**
-	 * Initiates a logger using the current class
-	 */
-	private static final Logger logger = LoggerFactory.getLogger(SQLProviderTestOLD.class);
-
-	
-	/**
-	 * Define a parameter tuple (name/type)
-	 * 
-	 * @author kuhn
-	 *
-	 */
-	static class Parameter {
-		String name;
-		String type;
-		
-		
-		/**
-		 * Constructor 
-		 * 
-		 * @param name  Parameter name
-		 * @param type  Parameter type
-		 */
-		Parameter(String name, String type) {
-			this.name = name;
-			this.type = type;
-		}
-		
-		
-		/**
-		 * Return parameter name
-		 * 
-		 * @return parameter name
-		 */
-		public String getName() {
-			return name;
-		}
-		
-		
-		/**
-		 * Return parameter type
-		 * 
-		 * @return parameter type
-		 */
-		public String getType() {
-			return type;
-		}
-	}
-	
-	
-	
-	
-	/**
-	 * Get operation name of operation definition 
-	 * 
-	 * @param opDef The operation definition string
-	 * @return Operation name
-	 */
-	public static String getOperation(String opDef) {
-		// Get operation name
-		return opDef.substring(0, opDef.indexOf("("));
-	}
-	
-	
-	
-	/**
-	 * Get parameter list of an operation definition
-	 * 
-	 * A parameter list contains of a name and of a type for each parameter+
-	 * 
-	 * @param opDef The operation definition string
-	 * @return Collection of Parameter definitions
-	 */
-	public static Collection<Parameter> getParameter(String opDef) {
-		// Return type
-		LinkedList<Parameter> result = new LinkedList<>();
-		
-		// Extract parameter sequence
-		String   callParameterStr  = opDef.substring(opDef.indexOf("(")+1, opDef.length()-1);
-		String[] callParameterList = callParameterStr.split(",");
-		
-		// Iterate all parameter. If no parameter is given, the loop will execute once with an empty String (length = 0)
-		for (String parameterDef: callParameterList) {
-			// Only process strings with a length > 0
-			if (parameterDef.length() == 0) continue;
-			
-			// Add parameter
-			result.add(new Parameter(parameterDef.substring(0, parameterDef.indexOf(":")).trim(), parameterDef.substring(parameterDef.indexOf(":")+1).trim().toLowerCase()));			
-		}
-		
-		// Return result
-		return result;
-	}
-	
-	
-
-	/**
-	 * Create a SQL string from an input SQL string with place holders in format $x with x being an integer number.
-	 * 
-	 * @param baseString SQL string with place holders
-	 * @param parameter Parameter values that place holders are substituted for
-	 * 
-	 * @return SQL string with parameter instead of place holders
-	 */
-	public static String getSQLString(String baseString, Collection<String> parameter) {
-		// Resulting SQL String
-		String result = baseString;
-		
-		// Replace place holders with parameter
-		// - Counter variable
-		int counter = 1;
-		// - Replace all place holders
-		for (String par: parameter) {
-			result = result.replace("$"+counter, par);
-			counter++;
-		}
-		
-		// Return SQL string with resolved parameter
-		return result;
-	}
-
-	
-	
-	public static void main(String[] args) throws SQLException {
-		logger.debug("Test");
-		
-		ISQLDriver sqlDriver = new SQLDriver("localhost:5432/basyx-sample-vibrations", "postgres", "admin", "jdbc:postgresql://", "org.postgresql.Driver");
-
-		
-		
-		Collection<String> sqlQuery1Params = new LinkedList<>();
-		sqlQuery1Params.add(Integer.valueOf(1).toString());
-		String     sqlQuery1String = getSQLString("SELECT * FROM vibrations.sensors WHERE vibrations.sensors.sensorid='$1'", sqlQuery1Params);
-		
-		ResultSet result1 = sqlDriver.sqlQuery(sqlQuery1String);
-		
-		logger.debug(""+result1);
-		logger.debug(""+result1.next());
-		logger.debug("ID   : "+result1.getString("sensorid"));
-		logger.debug("NAME : "+result1.getString("sensorname"));
-		logger.debug(""+result1.next());
-
-		
-		
-		Collection<String> sqlQuery2Params = new LinkedList<>();
-		sqlQuery2Params.add("vibrations.sensors.sensorid");
-		sqlQuery2Params.add(Integer.valueOf(1).toString());
-		String     sqlQuery2String = getSQLString("SELECT * FROM vibrations.sensors WHERE $1='$2'", sqlQuery2Params);
-		
-		ResultSet result2 = sqlDriver.sqlQuery(sqlQuery2String);
-		
-		logger.debug(""+result2);
-		logger.debug(""+result2.next());
-		logger.debug("ID   : "+result2.getString("sensorid"));
-		logger.debug("NAME : "+result2.getString("sensorname"));
-		logger.debug(""+result2.next());
-
-
-		
-		String call1 = "MapString()";
-		
-		logger.debug("- "+getOperation(call1));
-		logger.debug("- "+getParameter(call1));
-
-		
-		String call2 = "MapArray(sensorid:int, sensorname:String)";
-		
-		logger.debug("- "+getOperation(call2));
-		logger.debug("- "+getParameter(call2));
-		
-	}
-}
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/SQLSubModelProvider.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/SQLSubModelProvider.java
deleted file mode 100644
index 59697d6..0000000
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/SQLSubModelProvider.java
+++ /dev/null
@@ -1,511 +0,0 @@
-package org.eclipse.basyx.components.sqlprovider;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
-
-import org.eclipse.basyx.components.provider.BaseConfiguredProvider;
-import org.eclipse.basyx.components.sqlprovider.driver.SQLDriver;
-import org.eclipse.basyx.components.sqlprovider.query.DynamicSQLQuery;
-import org.eclipse.basyx.components.sqlprovider.query.DynamicSQLRunner;
-import org.eclipse.basyx.components.sqlprovider.query.DynamicSQLUpdate;
-import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaHandler;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-
-
-
-/**
- * Asset administration shell sub model provider that connects to SQL database
- * 
- * @author kuhn
- *
- */
-public class SQLSubModelProvider extends BaseConfiguredProvider {
-
-	/**
-	 * Initiates a logger using the current class
-	 */
-	private static final Logger logger = LoggerFactory.getLogger(SQLSubModelProvider.class);
-	
-	/**
-	 * SQL database user name
-	 */
-	protected String sqlUser = null;
-
-	/**
-	 * SQL database password
-	 */
-	protected String sqlPass = null;
-	
-	/**
-	 * SQL database path
-	 */
-	protected String sqlURL  = null;
-
-	
-	
-	/**
-	 * SQL database driver
-	 */
-	protected String sqlDriver = null;
-	
-	/**
-	 * SQL database query prefix
-	 */
-	protected String sqlPrefix = null;
-	
-	/**
-	 * An SQL driver instance to connect to the database
-	 */
-	protected SQLDriver driver;
-	
-	
-	/**
-	 * SQL property connections
-	 */
-	protected Set<String> sqlPropertyConnections = new HashSet<>();
-	
-
-	/**
-	 * SQL operation connections
-	 */
-	protected Set<String> sqlOperationConnections = new HashSet<>();
-
-	
-	
-	/**
-	 * Run queries to access properties via 'get' operation
-	 */
-	protected Map<String, DynamicSQLRunner> propertyGetQueries = new HashMap<>();
-
-	
-	/**
-	 * Run SQL update to access properties via 'set' operation
-	 */
-	protected Map<String, DynamicSQLRunner> propertySetQueries = new HashMap<>();
-
-	
-	/**
-	 * Run SQL update to access properties via 'create' operation
-	 */
-	protected Map<String, DynamicSQLRunner> propertyCreateQueries = new HashMap<>();
-
-
-	/**
-	 * Run SQL update to access properties via 'delete' operation
-	 */
-	protected Map<String, DynamicSQLRunner> propertyDeleteQueries = new HashMap<>();
-
-
-	
-	/**
-	 * SQL operations
-	 */
-	protected Map<String, DynamicSQLRunner> operations = new HashMap<>();
-
-	
-	/**
-	 * SQL operations that run as update operations. Not contained operations are query operations.
-	 */
-	protected Set<String> updateOperations = new HashSet<>();
-
-	
-	
-	
-	/**
-	 * Constructor
-	 */
-	public SQLSubModelProvider(Properties cfgValues) {
-		// Call base constructor
-		super(cfgValues);
-		
-		// Create sub model
-		submodelData = createSubModel(cfgValues);
-
-		// Load predefined elements from sub model
-		try {
-			setModelPropertyValue("", submodelData);
-		} catch (Exception e) {
-			e.printStackTrace();
-		}
-
-		
-		// Extract SQL properties
-		sqlUser = cfgValues.getProperty(
-				SQLPreconfiguredSubModelProvider.buildSqlCfgName(SQLPreconfiguredSubModelProvider.DBUSER));
-		sqlPass = cfgValues.getProperty(
-				SQLPreconfiguredSubModelProvider.buildSqlCfgName(SQLPreconfiguredSubModelProvider.DBPASS));
-		sqlURL  = cfgValues.getProperty(
-				SQLPreconfiguredSubModelProvider.buildSqlCfgName(SQLPreconfiguredSubModelProvider.DBURL));
-
-		// Extract SQL driver properties
-		sqlDriver = cfgValues.getProperty(
-				SQLPreconfiguredSubModelProvider.buildSqlCfgName(SQLPreconfiguredSubModelProvider.DRIVER));
-		sqlPrefix = cfgValues.getProperty(
-				SQLPreconfiguredSubModelProvider.buildSqlCfgName(SQLPreconfiguredSubModelProvider.PREFIX));
-		
-		// Create a SQL driver instance
-		driver = new SQLDriver(sqlURL, sqlUser, sqlPass, sqlPrefix, sqlDriver);
-		
-		// Load and parse SQL property and operation connections
-		sqlPropertyConnections.addAll(splitString(cfgValues.getProperty(
-				SQLPreconfiguredSubModelProvider.buildSqlCfgName(SQLPreconfiguredSubModelProvider.PROPERTIES))));
-		sqlOperationConnections.addAll(splitString(cfgValues.getProperty(
-				SQLPreconfiguredSubModelProvider.buildSqlCfgName(SQLPreconfiguredSubModelProvider.OPERATIONS))));
-
-		
-		
-		// Add properties
-		for (String propertyName: sqlPropertyConnections) createSQLProperty(propertyName, cfgValues);
-		
-		/*
-			// Try to parse parameter
-			propertyGetQueries.put(propertyName, createSQLOperation(propertyName+".get", cfgValues));
-			propertySetQueries.put(propertyName, createSQLOperation(propertyName+".set", cfgValues));
-			propertyCreateQueries.put(propertyName, createSQLOperation(propertyName+".create", cfgValues));
-			propertyDeleteQueries.put(propertyName, createSQLOperation(propertyName+".delete", cfgValues));
-			
-			
-			Map<String, Object> mapAccessors = VABLambdaProviderHelper.createMap((Supplier<?>) () -> {
-				return propertyMap_val;
-			}, (Consumer<Map<String, Object>>) (map) -> {
-				propertyMap_val = map;
-			}, (BiConsumer<String, Object>) (key, value) -> {
-				propertyMap_val.put(key, value);
-			}, (Consumer<Object>) (o) -> {
-				propertyMap_val.remove(o);
-			});
-
-		}*/
-		
-		
-		// Add operations
-		//for (String operationName: sqlOperationConnections) createSQLOperation(operationName, cfgValues); 
-		/*{
-			// Create operation
-			operations.put(operationName, createSQLOperation(operationName, cfgValues));
-			// Mark operation as update operation depending on operations/<operationName>_kind property value
-			try {
-				if (cfgValues.getProperty(operationName+"_kind").trim().equalsIgnoreCase("update")) {
-					updateOperations.add(operationName);
-				}
-			} catch (Exception e) {}
-		}*/
-	}
-	
-	
-	
-	/**
-	 * Create an SQL property
-	 */
-	protected void createSQLProperty(String name, Properties cfgValues) {
-		// Create Map with lambdas that hold SQL operations
-		Map<String, Object> value = new HashMap<>();
-		
-		// Get operation
-		{
-			// Get parameter
-			String queryString    = cfgValues.getProperty(name+".get");
-			String resultFilterOp = cfgValues.getProperty(name+".get.result");
-
-			// Trim query string and resultFilterOp (remove '"' at beginning and end)
-			queryString    = queryString.substring(1, queryString.length()-1);
-			try {resultFilterOp = resultFilterOp.substring(1, resultFilterOp.length()-1);} catch (NullPointerException | StringIndexOutOfBoundsException e) {}
-
-			// Create dynamic SQL query
-			value.put(VABLambdaHandler.VALUE_GET_SUFFIX, new DynamicSQLQuery(driver, queryString, resultFilterOp));
-		}
-		
-		// Set operation
-		{
-			// Get parameter
-			String updateString   = cfgValues.getProperty(name+".set");
-
-			// Trim query string and resultFilterOp (remove '"' at beginning and end)
-			updateString    = updateString.substring(1, updateString.length()-1);
-
-			// Create dynamic SQL query
-			value.put(VABLambdaHandler.VALUE_SET_SUFFIX, new DynamicSQLUpdate(driver, updateString));
-		}
-
-		// Delete operation
-		{
-			// Get parameter
-			String updateString   = cfgValues.getProperty(name+".delete");
-
-			// Trim query string and resultFilterOp (remove '"' at beginning and end)
-			updateString    = updateString.substring(1, updateString.length()-1);
-
-			// Create dynamic SQL query
-			value.put(VABLambdaHandler.VALUE_REMOVEKEY_SUFFIX, new DynamicSQLUpdate(driver, updateString));
-			value.put(VABLambdaHandler.VALUE_REMOVEOBJ_SUFFIX, new DynamicSQLUpdate(driver, updateString));
-		}
-		
-		// Create operation
-		{
-			// Get parameter
-			String updateString   = cfgValues.getProperty(name+".create");
-
-			// Trim query string and resultFilterOp (remove '"' at beginning and end)
-			updateString    = updateString.substring(1, updateString.length()-1);
-
-			// Create dynamic SQL query
-			value.put(VABLambdaHandler.VALUE_INSERT_SUFFIX, new DynamicSQLUpdate(driver, updateString));
-		}
-		
-		
-		logger.debug("Putting SQL:"+name);
-		// Add property as map of lambdas
-		submodelData.getProperties().put(name, createSubmodelElement(name, value, cfgValues));
-	}
-
-	
-	/**
-	 * Create a dynamic SQL operation
-	 */
-	protected DynamicSQLRunner createSQLOperation(String propertyName, Properties cfgValues) {/*
-		// Check parameter presence
-		if (!cfgValues.containsKey(propertyName)) return null;
-		
-		// Get parameter count and parameter count
-		int    parameterCount = Integer.parseInt(cfgValues.getProperty(propertyName+".parameter"));
-		String queryString    = cfgValues.getProperty(propertyName);
-		String resultFilterOp = cfgValues.getProperty(propertyName+".result");
-		
-		// Trim query string and resultFilterOp (remove '"' at beginning and end)
-		queryString    = queryString.substring(1, queryString.length()-1);
-		try {resultFilterOp = resultFilterOp.substring(1, resultFilterOp.length()-1);} catch (NullPointerException | StringIndexOutOfBoundsException e) {}
-		
-		// Create dynamic SQL query
-		DynamicSQLRunner sqlQuery = new DynamicSQLRunner(sqlURL, sqlUser, sqlPass, sqlPrefix, sqlDriver, parameterCount, queryString, resultFilterOp);
-
-		// Return created query
-		return sqlQuery;*/
-		
-		return null;
-	}
-	
-	
-	/**
-	 * Split a whitespace delimited string
-	 */
-	protected Collection<String> splitString(String input) {
-		// Return value
-		HashSet<String> result = new HashSet<>();
-		
-		// Split string into segments
-		for (String inputStr: input.split(" ")) result.add(inputStr.trim());
-		
-		// Return result
-		return result;
-	}
-	
-	
-	/**
-	 * Create a key list for an SQL statement
-	 *//*
-	protected String sqlCreateKeys(Collection<String> keys) {
-		// Return value builder
-		StringBuilder result = new StringBuilder();
-		
-		// Process keys
-		// - Flag that handles the first key
-		boolean isFirst = true;
-		// - Process keys
-		for (String key: keys) {if (!isFirst) result.append(","); else isFirst=false; result.append(key);}
-		
-		// Return string
-		return result.toString();
-	}*/
-	
-	
-	/**
-	 * Extract a list of values from a map
-	 *//*
-	protected String sqlCreateValues(Collection<Object> values) {
-		// Return value builder
-		StringBuilder result = new StringBuilder();
-		
-		// Process keys
-		// - Flag that handles the first key
-		boolean isFirst = true;
-		// - Process keys
-		for (Object key: values) {if (!isFirst) result.append(","); else isFirst=false; result.append("'"+key+"'");}
-		
-		// Return string
-		return result.toString();
-	}*/
-
-
-	
-	/**
-	 * Create (insert) a value into the SQL table
-	 *//*
-	@Override @SuppressWarnings("unchecked")
-	public void createValue(String propertyName, Object arg1) throws Exception {
-		// Set query
-		DynamicSQLRunner query = propertyCreateQueries.get(propertyName);
-		
-		// Null pointer check
-		if (query == null) return;
-		
-		// Create parameter array
-		Object[] parameter = new Object[2];
-		parameter[0] = sqlCreateKeys(((Map<String, Object>) arg1).keySet());
-		parameter[1] = sqlCreateValues(((Map<String, Object>) arg1).values());
-		
-		// Execute query and return result
-		query.runUpdate(parameter);
-	}*/
-
-
-	
-	/**
-	 * Delete a value from the SQL table
-	 *//*
-	@Override
-	public void deleteValue(String arg0) throws Exception {
-		// This is not implemented
-	}*/
-
-
-	
-	/**
-	 * Delete a value from the SQL table
-	 *//*
-	@Override @SuppressWarnings("unchecked")
-	public void deleteValue(String propertyName, Object arg1) throws Exception {
-		// Set query
-		DynamicSQLRunner query = propertyDeleteQueries.get(propertyName);
-		
-		// Null pointer check
-		if (query == null) return;
-
-		// Cast argument to collection
-		Collection<Object> parameterList = (Collection<Object>) arg1;
-		
-		// Create parameter array
-		Object[] parameter = new Object[parameterList.size()];
-		// - Copy parameter
-		int counter = 0; for (Object par: parameterList) parameter[counter++] = par;
-		
-		// Execute query and return result
-		query.runUpdate(parameter);
-	}*/
-
-	
-/*
-	@Override
-	public Map<String, IElementReference> getContainedElements(String arg0) {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
-
-	@Override
-	public String getElementScope(String arg0) {
-		logger.debug("GetScope:"+arg0);
-		// TODO Auto-generated method stub
-		return null;
-	}
-*/
-
-	
-	/**
-	 * Query the SQL database
-	 *//*
-	@Override
-	public Object getModelPropertyValue(String propertyName) {
-		// Get query
-		DynamicSQLRunner query = propertyGetQueries.get(propertyName);
-		
-		// Null pointer check
-		if (query == null) return null;
-		
-		// Execute query and return result
-		return query.runQuery();
-	}*/
-
-
-	
-	/**
-	 * Invoke operation with given parameter list
-	 *//*
-	@Override
-	public Object invokeOperation(String propertyName, Object[] parameter) throws Exception {
-		// Set query
-		DynamicSQLRunner query = operations.get(propertyName);
-		
-		// Null pointer check
-		if (query == null) return null;
-		
-		// Execute query and return result
-		if (updateOperations.contains(propertyName)) {
-			query.runUpdate(parameter); 
-			return null; 
-		} else {
-			return query.runQuery(parameter);
-		}
-	}*/
-
-
-	
-	/**
-	 * Invoke set operation with given parameter
-	 *//*
-	@Override @SuppressWarnings("unchecked")
-	public void setModelPropertyValue(String propertyName, Object arg1) throws Exception {
-		// Set query
-		DynamicSQLRunner query = propertySetQueries.get(propertyName);
-		
-		// Null pointer check
-		if (query == null) return;
-
-		logger.debug("LENC:"+arg1);
-
-		// Create parameter array
-		Object[] parameter = null;
-		// - Process collections
-		if (arg1 instanceof Collection) {
-			// Cast to collection
-			Collection<Object> parameterList = (Collection<Object>) arg1;
-			
-			// Create parameter array and copy parameter
-			parameter = new Object[parameterList.size()];
-			int counter = 0; for (Object par: parameterList) parameter[counter++] = par;
-		} else {
-			// Create parameter array and copy parameter
-			parameter = new Object[1];
-			parameter[0] = arg1;			
-		}
-		
-		
-		// Execute query and return result
-		query.runUpdate(parameter);
-	}*/
-
-
-	
-	/**
-	 * Invoke set operation with given parameter list
-	 *//*
-	@Override
-	public void setModelPropertyValue(String propertyName, Object... parameter) throws Exception {
-		// Set query
-		DynamicSQLRunner query = propertySetQueries.get(propertyName);
-		
-		// Null pointer check
-		if (query == null) return;
-		
-		logger.debug("LEN:"+parameter.length);
-		logger.debug("LEN-0:"+parameter[0]);
-
-		// Execute query and return result
-		query.runUpdate(parameter);
-	}*/
-}
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/driver/ISQLDriver.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/driver/ISQLDriver.java
deleted file mode 100644
index 37095d0..0000000
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/driver/ISQLDriver.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package org.eclipse.basyx.components.sqlprovider.driver;
-
-import java.sql.ResultSet;
-
-
-
-/**
- * Database access interface
- * 
- * @author kuhn
- *
- */
-public interface ISQLDriver {
-
-	
-	/**
-	 * Execute a SQL query
-	 */
-	public ResultSet sqlQuery(String queryString);
-
-	
-	/**
-	 * Execute a SQL update
-	 */
-	public void sqlUpdate(String updateString);
-}
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/driver/SQLDriver.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/driver/SQLDriver.java
deleted file mode 100644
index 94931ee..0000000
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/driver/SQLDriver.java
+++ /dev/null
@@ -1,221 +0,0 @@
-package org.eclipse.basyx.components.sqlprovider.driver;
-
-import java.sql.Connection;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Statement;
-
-import javax.sql.rowset.CachedRowSet;
-import javax.sql.rowset.RowSetFactory;
-import javax.sql.rowset.RowSetProvider;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.zaxxer.hikari.HikariDataSource;
-
-
-/**
- * Access SQL database
- * 
- * @author kuhn
- *
- */
-public class SQLDriver implements ISQLDriver {
-	private static Logger logger = LoggerFactory.getLogger(SQLDriver.class);
-
-	
-	/**
-	 * Store user name
-	 */
-	protected String userName = null;
-	
-	/**
-	 * Store password
-	 */
-	protected String password = null;
-
-	/**
-	 * Store path to database server
-	 */
-	protected String dbPath = null;
-	
-	
-	/**
-	 * Store query prefix
-	 */
-	protected String queryPrefix = null;
-	
-	
-	/**
-	 * Store driver class (with package name)
-	 */
-	protected String qualDriverClass = null;
-	
-	
-	/**
-	 * JDBC connection
-	 */
-	protected Connection connect = null;
-	
-	/**
-	 * Data source
-	 */
-	protected HikariDataSource ds = null;
-
-	
-	
-	
-	/**
-	 * Create a SQL driver and a SQL connection
-	 */
-	public SQLDriver(String path, String user, String pass, String qryPfx, String qDrvCls) {
-		// Store parameter
-		userName        = user;
-		password        = pass;
-		dbPath          = path;
-		queryPrefix     = qryPfx;
-		qualDriverClass = qDrvCls;
-		
-		// This will load the MySQL driver, each DB has its own driver
-		try {
-			Class.forName(qualDriverClass);
-		} catch (ClassNotFoundException e) {
-			logger.error("Could not init SQLDriver", e);
-		}
-	}
-	
-	
-	
-	/**
-	 * Execute a SQL query
-	 */
-	public CachedRowSet sqlQuery(String queryString) {
-		// Store SQL statement, flag that indicates whether the connection was created by this 
-		// operation (and needs to be closed), and result
-		Statement statement              = null;
-		CachedRowSet rowSet              = null;
-		
-		
-		// Access database
-		try {
-			// Open a connection with data source
-			openConnection();
-
-			// Statements allow to issue SQL queries to the database
-			statement = connect.createStatement();
-			
-			// ResultSet gets the result of the SQL query
-			ResultSet resultSet = statement.executeQuery(queryString);
-			
-			// Convert DB data to memory cache
-			rowSet = getCachedRowSet(resultSet);
-			
-			// Close connection with data source
-			closeConnection();
-		} catch (SQLException e) {
-			logger.error("sqlQuery failed", e);
-		}
-		
-		// Return result of query
-		return rowSet;
-	}
-	
-	
-	
-	/**
-	 * Execute a SQL update
-	 */
-	public void sqlUpdate(String updateString) {
-		// Store SQL statement
-		Statement statement              = null;
-		
-		// Access database
-		try {
-			// Open a connection with data source
-			openConnection();
-
-			// Statements allow to issue SQL queries to the database
-			statement = connect.createStatement();
-
-			// ResultSet gets the result of the SQL query
-			statement.executeUpdate(updateString);
-
-			// Close connection with data source
-			closeConnection();
-		} catch (SQLException e) {
-			logger.error("sqlUpdate failed", e);
-		}
-	}
-	
-	
-	
-	/**
-	 * Open connection
-	 */
-	public void openConnection() {
-		// Access database
-		try {
-			// Open connection
-			if (connect == null) {
-				openDataSource();
-				connect = ds.getConnection();	
-			}
-		} catch (SQLException e) {
-			logger.error("Failed to open sql driver connection", e);
-		}
-	}
-	
-	
-	/**
-	 * Close connection
-	 */
-	public void closeConnection() {
-		// Access database
-		try {
-			// Close connection
-			if (connect != null) {
-				connect.close();
-				connect = null;
-			}
-		} catch (SQLException e) {
-			logger.error("Failed to close sql driver connection", e);
-		}
-	}
-	
-	
-	/**
-	 * Get connection
-	 */
-	public Connection getConnection() {
-		return connect;
-	}
-	
-	
-	/**
-	 * Indicate if driver has open connection
-	 */
-	public boolean hasOpenConnection() {
-		return (connect == null);
-	}
-	
-	/**
-	 * Open Data source
-	*/
-	private void openDataSource() {
-		if (ds == null) {
-			ds = new HikariDataSource();
-			ds.setJdbcUrl(queryPrefix+dbPath);
-			ds.setUsername(userName);
-			ds.setPassword(password);
-		}
-	}
-	
-	private CachedRowSet getCachedRowSet(ResultSet resultSet) throws SQLException {
-		RowSetFactory factory = RowSetProvider.newFactory();
-		CachedRowSet rowset = factory.createCachedRowSet();
-		rowset.populate(resultSet);
-		return rowset;
-	}
-}
-
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/query/DynamicSQLOperation.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/query/DynamicSQLOperation.java
deleted file mode 100644
index 9b8449a..0000000
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/query/DynamicSQLOperation.java
+++ /dev/null
@@ -1,111 +0,0 @@
-package org.eclipse.basyx.components.sqlprovider.query;
-
-import java.lang.reflect.InvocationTargetException;
-import java.sql.ResultSet;
-import java.util.Collection;
-import java.util.LinkedList;
-import java.util.function.Function;
-
-import org.eclipse.basyx.components.sqlprovider.driver.ISQLDriver;
-import org.eclipse.basyx.components.tools.propertyfile.opdef.OperationDefinition;
-import org.eclipse.basyx.components.tools.propertyfile.opdef.Parameter;
-import org.eclipse.basyx.components.tools.propertyfile.opdef.ResultFilter;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-
-
-/**
- * Implement a generic SQL query
- * 
- * @author kuhn
- *
- */
-public class DynamicSQLOperation extends DynamicSQLRunner implements Function<Object[], Object> {
-	private static Logger logger = LoggerFactory.getLogger(DynamicSQLOperation.class);
-
-	
-	/**
-	 * Store SQL query string with place holders ($x)
-	 */
-	protected String sqlQueryString = null;
-	
-	
-	/**
-	 * Store SQL result filter
-	 */
-	protected String resultFilterString = null;
-	
-	
-	
-	
-	
-	/**
-	 * Constructor
-	 */
-	public DynamicSQLOperation(ISQLDriver driver, String query, String sqlResultFilter) {
-		// Invoke base constructor
-		super(driver);
-		
-		// Store parameter count and SQL query string
-		sqlQueryString         = query;
-		resultFilterString     = sqlResultFilter;
-	}
-
-	
-	/**
-	 * Constructor
-	 */
-	public DynamicSQLOperation(String path, String user, String pass, String qryPfx, String qDrvCls, String query, String sqlResultFilter) {
-		// Invoke base constructor
-		super(path, user, pass, qryPfx, qDrvCls);
-		
-		// Store parameter count and SQL query string
-		sqlQueryString         = query;
-		resultFilterString     = sqlResultFilter;
-	}
-	
-	
-	/**
-	 * Execute query with given parameter
-	 */
-	@Override
-	public Object apply(Object[] parameter) {
-		// Create list of query parameter
-		Collection<String> sqlQueryParameter = new LinkedList<>();
-		// - Add parameter
-		for (Object par: parameter) sqlQueryParameter.add(par.toString());
-		
-		// Apply parameter and create SQL query string
-		String sqlQuery = OperationDefinition.getSQLString(sqlQueryString, sqlQueryParameter);
-		
-		logger.debug("Running SQL query:" + sqlQuery);
-
-		// Execute SQL query
-		ResultSet sqlResult = sqlDriver.sqlQuery(sqlQuery);
-		
-		// Extract input parameter definition
-		Collection<Parameter> resultParameter = OperationDefinition.getParameter(resultFilterString);
-
-		// Process result
-		try {
-			// Create inner parameter array for call
-			Object[] callParameterInner = new Object[resultParameter.size()];
-			int i=0; for (String column: getColumnNames(resultParameter)) callParameterInner[i++]=column;
-
-			// Create parameter array for call
-			Object[] callParameter = new Object[2];
-			callParameter[0] = sqlResult;
-			callParameter[1] = callParameterInner;
-			
-			// Invoke result filter operation using static invocation
-			return ResultFilter.class.getMethod(OperationDefinition.getOperation(resultFilterString), getMethodParameter(resultParameter)).invoke(null, callParameter);
-		} catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
-			logger.error("Could not invoke dynamic sql operation", e);
-		}
-		
-		// No result
-		return null;
-	}
-}
-
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/query/DynamicSQLQuery.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/query/DynamicSQLQuery.java
deleted file mode 100644
index 6a5befe..0000000
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/query/DynamicSQLQuery.java
+++ /dev/null
@@ -1,153 +0,0 @@
-package org.eclipse.basyx.components.sqlprovider.query;
-
-import java.lang.reflect.InvocationTargetException;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.Collection;
-import java.util.Map;
-import java.util.function.Supplier;
-
-import org.eclipse.basyx.components.sqlprovider.driver.ISQLDriver;
-import org.eclipse.basyx.components.tools.propertyfile.opdef.OperationDefinition;
-import org.eclipse.basyx.components.tools.propertyfile.opdef.Parameter;
-import org.eclipse.basyx.components.tools.propertyfile.opdef.ResultFilter;
-
-
-
-/**
- * Implement a generic SQL query
- * 
- * @author kuhn
- *
- */
-public class DynamicSQLQuery extends DynamicSQLRunner implements Supplier<Object> {
-
-	
-	/**
-	 * Store SQL query string with place holders ($x)
-	 */
-	protected String sqlQueryString = null;
-	
-	
-	/**
-	 * Store SQL result filter
-	 */
-	protected String resultFilterString = null;
-	
-	
-	
-	
-	
-	/**
-	 * Constructor that accepts a driver
-	 */
-	public DynamicSQLQuery(ISQLDriver driver, String query, String sqlResultFilter) {
-		// Invoke base constructor
-		super(driver);
-
-		// Store SQL query string and result filter
-		sqlQueryString         = query;
-		resultFilterString     = sqlResultFilter;
-	}
-
-	
-	/**
-	 * Constructor
-	 */
-	public DynamicSQLQuery(String path, String user, String pass, String qryPfx, String qDrvCls, String query, String sqlResultFilter) {
-		// Invoke base constructor
-		super(path, user, pass, qryPfx, qDrvCls);
-		
-		// Store SQL query string and result filter
-		sqlQueryString         = query;
-		resultFilterString     = sqlResultFilter;
-	}
-
-	
-	/**
-	 * Execute query without parameter
-	 */
-	@Override
-	public Object get() {
-		// Execute SQL query
-		ResultSet sqlResult = sqlDriver.sqlQuery(sqlQueryString);
-
-		// Process result
-		return processResult(sqlResult);
-	}
-	
-	
-	/**
-	 * Execute query without parameter, do not post process result
-	 */
-	public ResultSet getRaw() {
-		// Execute SQL query
-		return sqlDriver.sqlQuery(sqlQueryString);
-	}
-
-	
-	/**
-	 * Execute query without parameter
-	 */
-	public Object get(Map<String,Object> param) {
-		// Apply parameter and create SQL query string
-		String sqlQuery = OperationDefinition.getSQLString(sqlQueryString, param);
-
-		// Execute SQL query
-		ResultSet sqlResult = sqlDriver.sqlQuery(sqlQuery);
-
-		// Process result
-		return processResult(sqlResult);
-	}
-
-	
-	/**
-	 * Execute query without parameter, do not post process result
-	 */
-	public ResultSet getRaw(Map<String,Object> param) {
-		// Apply parameter and create SQL query string
-		String sqlQuery = OperationDefinition.getSQLString(sqlQueryString, param);
-
-		// Execute SQL query
-		return sqlDriver.sqlQuery(sqlQuery);
-	}
-	
-	
-	
-	/**
-	 * Process result parameter
-	 */
-	protected Object processResult(ResultSet sqlResult) {
-		// Extract input parameter definition
-		Collection<Parameter> parameter = OperationDefinition.getParameter(resultFilterString);
-
-		// Process result
-		try {
-			// Create inner parameter array for call
-			Object[] callParameterInner = new Object[parameter.size()];
-			int i=0; for (String column: getColumnNames(parameter)) callParameterInner[i++]=column;
-
-			// Create parameter array for call
-			Object[] callParameter = new Object[2];
-			callParameter[0] = sqlResult;
-			callParameter[1] = callParameterInner;
-
-			// Invoke result filter operation using static invocation
-			Object result = ResultFilter.class.getMethod(OperationDefinition.getOperation(resultFilterString), getMethodParameter(parameter)).invoke(null, callParameter);
-			
-			// Close result set
-			sqlResult.close();
-			
-			// Return result
-			return result;
-			
-		} catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | SQLException e) {
-			// Print exception to console
-			e.printStackTrace();
-		}
-
-		// No result
-		return null;
-	}
-}
-
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/query/DynamicSQLRunner.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/query/DynamicSQLRunner.java
deleted file mode 100644
index d3a3a88..0000000
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/query/DynamicSQLRunner.java
+++ /dev/null
@@ -1,78 +0,0 @@
-package org.eclipse.basyx.components.sqlprovider.query;
-
-import java.sql.ResultSet;
-import java.util.Collection;
-import java.util.LinkedList;
-import org.eclipse.basyx.components.sqlprovider.driver.ISQLDriver;
-import org.eclipse.basyx.components.sqlprovider.driver.SQLDriver;
-import org.eclipse.basyx.components.tools.propertyfile.opdef.Parameter;
-
-
-
-
-/**
- * SQL query operation
- * 
- * @author kuhn
- *
- */
-public class DynamicSQLRunner {
-
-	
-	/**
-	 * Store SQL driver instance
-	 */
-	protected ISQLDriver sqlDriver = null;
-	
-	
-	
-	
-	
-	/**
-	 * Constructor that accepts a driver
-	 */
-	public DynamicSQLRunner(ISQLDriver driver) {
-		// Store SQL driver instance
-		sqlDriver = driver;
-	}
-
-	
-	/**
-	 * Constructor
-	 */
-	public DynamicSQLRunner(String path, String user, String pass, String qryPfx, String qDrvCls) {
-		// Create SQL driver instance
-		sqlDriver = new SQLDriver(path, user, pass, qryPfx, qDrvCls);
-	}
-	
-	
-	
-	/**
-	 * Get method parameter definition
-	 */
-	protected Class<?>[] getMethodParameter(Collection<Parameter> parameter) {
-		// Store operation signature
-		Class<?>[] result = new Class<?>[2];
-		
-		// Operation signature is ResultSet and a list of string parameter that define column names
-		result[0] = ResultSet.class;
-		result[1] = Object[].class;
-		
-		// Return signature
-		return result;
-	}
-	
-	
-	/**
-	 * Get column names
-	 */
-	protected Collection<String> getColumnNames(Collection<Parameter> parameter) {
-		// Return value
-		Collection<String> result = new LinkedList<>();
-		
-		for (Parameter par: parameter) result.add(par.getName());
-		
-		return result;
-	}
-}
-
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/query/DynamicSQLUpdate.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/query/DynamicSQLUpdate.java
deleted file mode 100644
index 773824b..0000000
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/query/DynamicSQLUpdate.java
+++ /dev/null
@@ -1,71 +0,0 @@
-package org.eclipse.basyx.components.sqlprovider.query;
-
-import java.util.Map;
-import java.util.function.Consumer;
-
-import org.eclipse.basyx.components.sqlprovider.driver.ISQLDriver;
-import org.eclipse.basyx.components.tools.propertyfile.opdef.OperationDefinition;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-
-
-/**
- * Implement a generic SQL query
- * 
- * @author kuhn
- *
- */
-public class DynamicSQLUpdate extends DynamicSQLRunner implements Consumer<Map<String,Object>> {
-	private static Logger logger = LoggerFactory.getLogger(DynamicSQLUpdate.class);
-
-	/**
-	 * Store SQL query string with place holders ($x)
-	 */
-	protected String sqlQueryString = null;
-	
-	
-	
-	
-	/**
-	 * Constructor
-	 */
-	public DynamicSQLUpdate(ISQLDriver driver, String query) {
-		// Invoke base constructor
-		super(driver);
-
-		// Store parameter count and SQL query string
-		sqlQueryString         = query;
-	}
-
-	
-	/**
-	 * Constructor
-	 */
-	public DynamicSQLUpdate(String path, String user, String pass, String qryPfx, String qDrvCls, String query) {
-		// Invoke base constructor
-		super(path, user, pass, qryPfx, qDrvCls);
-		
-		// Store parameter count and SQL query string
-		sqlQueryString         = query;
-	}
-	
-
-
-	/**
-	 * Execute update with given parameter
-	 */
-	@Override
-	public void accept(Map<String,Object> parameter) {
-		logger.debug("(Parameters) Running SQL update: " + parameter);
-
-		// Apply parameter and create SQL query string
-		String sqlQuery = OperationDefinition.getSQLString(sqlQueryString, parameter);
-		
-		logger.debug("(Query) Running SQL update:" + sqlQuery);
-
-		// Execute SQL query
-		sqlDriver.sqlUpdate(sqlQuery);
-	}
-}
-
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/tools/propertyfile/opdef/OperationDefinition.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/tools/propertyfile/opdef/OperationDefinition.java
index 659be20..4db6996 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/tools/propertyfile/opdef/OperationDefinition.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/tools/propertyfile/opdef/OperationDefinition.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.components.tools.propertyfile.opdef;
 
 import java.util.Collection;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/tools/propertyfile/opdef/Parameter.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/tools/propertyfile/opdef/Parameter.java
index 197aba9..5b18e59 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/tools/propertyfile/opdef/Parameter.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/tools/propertyfile/opdef/Parameter.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.components.tools.propertyfile.opdef;
 
 
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/tools/propertyfile/opdef/ResultFilter.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/tools/propertyfile/opdef/ResultFilter.java
index f7313ff..38d1851 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/tools/propertyfile/opdef/ResultFilter.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/tools/propertyfile/opdef/ResultFilter.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.components.tools.propertyfile.opdef;
 
 
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/xml/XMLAASBundleFactory.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/xml/XMLAASBundleFactory.java
index 3aac43f..751dea4 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/xml/XMLAASBundleFactory.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/xml/XMLAASBundleFactory.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.components.xml;
 
 import java.io.IOException;
@@ -15,11 +24,12 @@
 import org.eclipse.basyx.aas.metamodel.api.parts.asset.IAsset;
 import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
 import org.eclipse.basyx.aas.metamodel.map.parts.Asset;
-import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
 import org.eclipse.basyx.submodel.metamodel.api.qualifier.IIdentifiable;
 import org.eclipse.basyx.submodel.metamodel.api.reference.IKey;
 import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
 import org.eclipse.basyx.support.bundle.AASBundle;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.xml.sax.SAXException;
@@ -38,16 +48,6 @@
 	private String content;
 
 	/**
-	 * Internal exception used to indicate that the resource was not found
-	 * 
-	 * @author schnicke
-	 *
-	 */
-	private class ResourceNotFoundException extends Exception {
-		private static final long serialVersionUID = -1247012719907370743L;
-	}
-
-	/**
 	 * 
 	 * @param xmlContent
 	 *            the content of the XML
@@ -72,7 +72,7 @@
 		XMLToMetamodelConverter converter = new XMLToMetamodelConverter(content);
 
 		List<IAssetAdministrationShell> shells = converter.parseAAS();
-		List<ISubModel> submodels = converter.parseSubmodels();
+		List<ISubmodel> submodels = converter.parseSubmodels();
 
 		List<IAsset> assets = converter.parseAssets();
 
@@ -89,7 +89,7 @@
 			}
 
 			// Retrieve submodels
-			Set<ISubModel> currentSM = retrieveSubmodelsForAAS(submodels, shell);
+			Set<ISubmodel> currentSM = retrieveSubmodelsForAAS(submodels, shell);
 			bundles.add(new AASBundle(shell, currentSM));
 		}
 
@@ -103,12 +103,12 @@
 	 * @param shell
 	 * @return
 	 */
-	private Set<ISubModel> retrieveSubmodelsForAAS(List<ISubModel> submodels, IAssetAdministrationShell shell) {
-		Set<ISubModel> currentSM = new HashSet<>();
+	private Set<ISubmodel> retrieveSubmodelsForAAS(List<ISubmodel> submodels, IAssetAdministrationShell shell) {
+		Set<ISubmodel> currentSM = new HashSet<>();
 
 		for (IReference submodelRef : shell.getSubmodelReferences()) {
 			try {
-				ISubModel sm = getByReference(submodelRef, submodels);
+				ISubmodel sm = getByReference(submodelRef, submodels);
 				currentSM.add(sm);
 				logger.debug("Found Submodel " + sm.getIdShort() + " for AAS " + shell.getIdShort());
 			} catch (ResourceNotFoundException e) {
@@ -129,16 +129,23 @@
 	 * @throws ResourceNotFoundException
 	 */
 	private <T extends IIdentifiable> T getByReference(IReference ref, List<T> submodels) throws ResourceNotFoundException {
+		IKey lastKey = null;
 		// It may be that only one key fits to the Submodel contained in the XML
 		for (IKey key : ref.getKeys()) {
+			lastKey = key;
 			// There will only be a single submodel matching the identification at max
 			Optional<T> match = submodels.stream().filter(s -> s.getIdentification().getId().equals(key.getValue())).findFirst();
 			if (match.isPresent()) {
 				return match.get();
 			}
 		}
+		if (lastKey == null) {
+			throw new ResourceNotFoundException("Could not resolve reference without keys");
+		} else {
+			throw new ResourceNotFoundException("Could not resolve reference with last key " + lastKey.getValue());
+		}
 
 		// If no identifiable is found, indicate it by throwing an exception
-		throw new ResourceNotFoundException();
+
 	}
 }
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/models/controlcomponent/ControlComponent.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/models/controlcomponent/ControlComponent.java
index c005711..4458a3c 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/models/controlcomponent/ControlComponent.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/models/controlcomponent/ControlComponent.java
@@ -1,10 +1,18 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.models.controlcomponent;
 
 import java.io.Serializable;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.LinkedList;
-import java.util.List;
 import java.util.Map;
 import java.util.function.Function;
 
@@ -19,48 +27,32 @@
 public abstract class ControlComponent extends HashMap<String, Object> {
 
 	// Miscellaneous String constants
-	private static final String STATUS = "status";
-	private static final String ORDER_LIST = "orderList";
-	private static final String OCCUPIERID_LOCAL = "LOCAL";
-	private static final String OPERATIONS = "operations";
-	private static final String SERVICE = "service";
+	public static final String STATUS = "STATUS";
+	public static final String OPERATIONS = "OPERATIONS";
 
 	// String constants for operations
-	public static final String OPERATION_CLEAR = "clear";
-	public static final String OPERATION_STOP = "stop";
-	public static final String OPERATION_ABORT = "abort";
-	public static final String OPERATION_UNSUSPEND = "unsuspend";
-	public static final String OPERATION_SUSPEND = "suspend";
-	public static final String OPERATION_UNHOLD = "unhold";
-	public static final String OPERATION_HOLD = "hold";
-	public static final String OPERATION_RESET = "reset";
-	public static final String OPERATION_START = "start";
-	public static final String OPERATION_SIMULATION = "simulation";
-	public static final String OPERATION_MANUAL = "manual";
-	public static final String OPERATION_AUTO = "auto";
-	public static final String OPERATION_SEMIAUTO = "semiauto";
-	public static final String OPERATION_PRIORITY = "priority";
-	public static final String OPERATION_OCCUPY = "occupy";
-	public static final String OPERATION_FREE = "free";
-	public static final String OPERATION_BSTATE = "bstate";
+	public static final String OPERATION_CLEAR = "CLEAR";
+	public static final String OPERATION_STOP = "STOP";
+	public static final String OPERATION_ABORT = "ABORT";
+	public static final String OPERATION_RESET = "RESET";
+	public static final String OPERATION_START = "START";
+	public static final String OPERATION_MANUAL = "MANUAL";
+	public static final String OPERATION_AUTO = "AUTO";
+	public static final String OPERATION_PRIORITY = "PRIO";
+	public static final String OPERATION_OCCUPY = "OCCUPY";
+	public static final String OPERATION_FREE = "FREE";
 
 	// String constants for setting execution state
 	public static final String CMD = "cmd";
 
-	// String constants for overwrite
-	private static final String LOCAL_OVERWRITE_FREE = "localOverwriteFree";
-	private static final String LOCAL_OVERWRITE = "localOverwrite";
-
 	// String constants for status
-	private static final String PREV_ERROR = "prevError";
-	private static final String ERROR_STATE = "errorState";
-	private static final String WORK_STATE = "workState";
-	private static final String OP_MODE = "opMode";
-	private static final String EX_STATE = "exState";
-	private static final String EX_MODE = "exMode";
-	private static final String LAST_OCCUPIER = "lastOccupier";
-	private static final String OCCUPIER = "occupier";
-	private static final String OCCUPATION_STATE = "occupationState";
+	public static final String ERROR_STATE = "ER";
+	public static final String WORK_STATE = "WORKST";
+	public static final String OP_MODE = "OPMODE";
+	public static final String EX_STATE = "EXST";
+	public static final String EX_MODE = "EXMODE";
+	public static final String OCCUPIER = "OCCUPIER";
+	public static final String OCCUPATION_STATE = "OCCST";
 
 	/**
 	 * The status map implements the service/ substructure of the control component structure. It also 
@@ -84,13 +76,11 @@
 			// Populate control component "status" sub structure 
 			put(OCCUPATION_STATE, OccupationState.FREE.getValue()); // Occupation state: FREE
 			put(OCCUPIER, "");                      		// Occupier: none
-			put(LAST_OCCUPIER, "");                  		// Last occupier: none
 			put(EX_MODE, ExecutionMode.AUTO.getValue()); // Execution mode: AUTO
 			put(EX_STATE, ExecutionState.IDLE.getValue()); // Execution state: IDLE
 			put(OP_MODE, "");                        		// Component specific operation mode (e.g. active service)
 			put(WORK_STATE, "");                     		// Component specific work state
 			put(ERROR_STATE, "");                    		// Component error state
-			put(PREV_ERROR, "");                     		// Component previous error
 		}
 		
 		
@@ -119,13 +109,11 @@
 			switch(key) {
 				case OCCUPATION_STATE: for (ControlComponentChangeListener listener: listeners) listener.onNewOccupationState(OccupationState.byValue((int) value)); break;
 				case OCCUPIER:         for (ControlComponentChangeListener listener: listeners) listener.onNewOccupier(value.toString()); break;
-				case LAST_OCCUPIER:    for (ControlComponentChangeListener listener: listeners) listener.onLastOccupier(value.toString()); break;
 				case EX_MODE:          for (ControlComponentChangeListener listener: listeners) listener.onChangedExecutionMode(ExecutionMode.byValue((int) value)); break;
 				case EX_STATE:         for (ControlComponentChangeListener listener: listeners) listener.onChangedExecutionState(ExecutionState.byValue(value.toString())); break;
 				case OP_MODE:          for (ControlComponentChangeListener listener: listeners) listener.onChangedOperationMode(value.toString()); break;
 				case WORK_STATE:       for (ControlComponentChangeListener listener: listeners) listener.onChangedWorkState(value.toString()); break;
 				case ERROR_STATE:      for (ControlComponentChangeListener listener: listeners) listener.onChangedErrorState(value.toString()); break;
-				case PREV_ERROR:       for (ControlComponentChangeListener listener: listeners) listener.onChangedPrevError(value.toString()); break;
 			}
 						
 			// Return result
@@ -145,7 +133,7 @@
 	/**
 	 * Operations map
 	 */
-	protected Map<String, Object> operations = new HashMap<String, Object>();
+	protected Map<String, Function<?, ?>> operations = new HashMap<>();
 	
 	
 	/**
@@ -173,8 +161,6 @@
 	 */
 	public ControlComponent() {
 		// Add control component output signals to map
-		// - Order list
-		put(ORDER_LIST, new LinkedList<String>());
 		// - "status" sub structure
 		status = new StatusMap();
 		put(STATUS, status);
@@ -182,85 +168,51 @@
 		// Input signals
 		// - Command / stores last command
 		put(CMD, "");                           // No command
-		put(LOCAL_OVERWRITE, "");                // Local override signal
-		put(LOCAL_OVERWRITE_FREE, "");            // Local override release signal
 		
 		// Operations
 		// - Add "operations" sub structure
 		put(OPERATIONS, operations);
-		// - Service operations
-		Map<String, Function<?, ?>> serviceOperations = new HashMap<>();
 		// - Populate service operations
-		serviceOperations.put(OPERATION_FREE, (Function<Object[], Void> & Serializable) (v) -> {
+		operations.put(OPERATION_FREE, (Function<Object[], Void> & Serializable) (v) -> {
 			freeControlComponent((String) v[0]);
 			return null;
 		});
-		serviceOperations.put(OPERATION_OCCUPY, (Function<Object[], Void> & Serializable) (v) -> {
+		operations.put(OPERATION_OCCUPY, (Function<Object[], Void> & Serializable) (v) -> {
 			occupyControlComponent((String) v[0]);
 			return null;
 		});
-		serviceOperations.put(OPERATION_PRIORITY, (Function<Object[], Void> & Serializable) (v) -> {
+		operations.put(OPERATION_PRIORITY, (Function<Object[], Void> & Serializable) (v) -> {
 			priorityOccupation((String) v[0]);
 			return null;
 		});
-		serviceOperations.put(OPERATION_AUTO, (Function<Object, Void> & Serializable) (v) -> {
+		operations.put(OPERATION_AUTO, (Function<Object, Void> & Serializable) (v) -> {
 			this.setExecutionMode(ExecutionMode.AUTO);
 			return null;
 		});
-		serviceOperations.put(OPERATION_SEMIAUTO, (Function<Object, Void> & Serializable) (v) -> {
-			this.setExecutionMode(ExecutionMode.SEMIAUTO);
-			return null;
-		});
-		serviceOperations.put(OPERATION_MANUAL, (Function<Object, Void> & Serializable) (v) -> {
+		operations.put(OPERATION_MANUAL, (Function<Object, Void> & Serializable) (v) -> {
 			this.setExecutionMode(ExecutionMode.MANUAL);
 			return null;
 		});
-		serviceOperations.put(OPERATION_SIMULATION, (Function<Object, Void> & Serializable) (v) -> {
-			this.setExecutionMode(ExecutionMode.SIMULATION);
-			return null;
-		});
-		serviceOperations.put(OPERATION_START, (Function<Object, Void> & Serializable) (v) -> {
+		operations.put(OPERATION_START, (Function<Object, Void> & Serializable) (v) -> {
 			this.changeExecutionState(ExecutionOrder.START.getValue());
 			return null;
 		});
-		serviceOperations.put(OPERATION_RESET, (Function<Object, Void> & Serializable) (v) -> {
+		operations.put(OPERATION_RESET, (Function<Object, Void> & Serializable) (v) -> {
 			this.changeExecutionState(ExecutionOrder.RESET.getValue());
 			return null;
 		});
-		serviceOperations.put(OPERATION_HOLD, (Function<Object, Void> & Serializable) (v) -> {
-			this.changeExecutionState(ExecutionOrder.HOLD.getValue());
-			return null;
-		});
-		serviceOperations.put(OPERATION_UNHOLD, (Function<Object, Void> & Serializable) (v) -> {
-			this.changeExecutionState(ExecutionOrder.UNHOLD.getValue());
-			return null;
-		});
-		serviceOperations.put(OPERATION_SUSPEND, (Function<Object, Void> & Serializable) (v) -> {
-			this.changeExecutionState(ExecutionOrder.SUSPEND.getValue());
-			return null;
-		});
-		serviceOperations.put(OPERATION_UNSUSPEND, (Function<Object, Void> & Serializable) (v) -> {
-			this.changeExecutionState(ExecutionOrder.UNSUSPEND.getValue());
-			return null;
-		});
-		serviceOperations.put(OPERATION_ABORT, (Function<Object, Void> & Serializable) (v) -> {
+		operations.put(OPERATION_ABORT, (Function<Object, Void> & Serializable) (v) -> {
 			this.changeExecutionState(ExecutionOrder.ABORT.getValue());
 			return null;
 		});
-		serviceOperations.put(OPERATION_STOP, (Function<Object, Void> & Serializable) (v) -> {
+		operations.put(OPERATION_STOP, (Function<Object, Void> & Serializable) (v) -> {
 			this.changeExecutionState(ExecutionOrder.STOP.getValue());
 			return null;
 		});
-		serviceOperations.put(OPERATION_CLEAR, (Function<Object, Void> & Serializable) (v) -> {
+		operations.put(OPERATION_CLEAR, (Function<Object, Void> & Serializable) (v) -> {
 			this.changeExecutionState(ExecutionOrder.CLEAR.getValue());
 			return null;
 		});
-		serviceOperations.put(OPERATION_BSTATE, (Function<Object, Void> & Serializable) (v) -> {
-			this.setOperationMode("BSTATE");
-			return null;
-		});
-		// - Add service operations to sub structure
-		operations.put(SERVICE, serviceOperations);
 	}
 
 	
@@ -297,17 +249,7 @@
 	public void removeControlComponentChangeListener(ControlComponentChangeListener listener) {
 		listeners.remove(listener);
 	}
-	
 
-	/**
-	 * Get "operations" map
-	 */
-	@SuppressWarnings("unchecked")
-	protected Map<String, Function<?, ?>> getServiceOperationMap() {
-		return (Map<String, Function<?, ?>>) operations.get(SERVICE);
-	}
-	
-	
 	
 	/**
 	 * Update an value
@@ -325,8 +267,6 @@
 		// Process variable changes
 		switch(key) {
 			case CMD: 			   changeExecutionState(value.toString()); break;
-			case LOCAL_OVERWRITE: 	   invokeLocalOverwrite(); break;
-			case LOCAL_OVERWRITE_FREE: clearLocalOverwrite(); break;
 		}
 					
 		// Return result
@@ -341,8 +281,6 @@
 		// Update occupier if sender is occupier
 		if (senderId.equals(this.getOccupierID())) {
 			// Get occupier from last occupier and reset last occupier
-			this.setOccupierID(this.getLastOccupierID());
-			this.setLastOccupierID("");
 			// Component is free if last occupier is empty, occupied otherwise
 			if (this.getOccupierID().isEmpty()) this.setOccupationState(OccupationState.FREE); else this.setOccupationState(OccupationState.OCCUPIED);
 		}
@@ -364,40 +302,11 @@
 	private void priorityOccupation(String occupier) {
 		// Occupy component if component is FREE or OCCUPIED
 		if ((this.getOccupationState().equals(OccupationState.FREE)) || (this.getOccupationState().equals(OccupationState.OCCUPIED))) {
-			this.setLastOccupierID(this.getOccupierID());
 			this.setOccupierID(occupier); 
 			this.setOccupationState(OccupationState.PRIORITY);
 		}
 	}
-	
-	
-	/**
-	 * Helper method - local overwrite of OCCUPIED or PRIORITY occupation
-	 */
-	private void invokeLocalOverwrite() {
-		// Store current occupier because we need to restore it later
-		savedOccupierID = this.getOccupierID();
 		
-		// Enter local overwrite state
-		this.setOccupationState(OccupationState.LOCAL);
-		this.setOccupierID(OCCUPIERID_LOCAL);
-	}
-	
-	
-	/**
-	 * Helper method - clear local occupier overwrite status
-	 */
-	private void clearLocalOverwrite() {
-		// Restore current occupier ID
-		this.setOccupierID(savedOccupierID);
-
-		// Restore occupier state based on variables
-		if (this.getOccupierID().isEmpty()) this.setOccupationState(OccupationState.FREE); else
-			if (this.getLastOccupierID().isEmpty()) this.setOccupationState(OccupationState.OCCUPIED); else 
-				this.setOccupationState(OccupationState.PRIORITY);
-	}
-	
-	
 	/**
 	 * Change execution state based on execution order
 	 */
@@ -546,37 +455,6 @@
 				throw new RuntimeException("Unexpected state complete order in state "+getExecutionState());
 		}
 	}
-		
-	
-	/**
-	 * Get order list
-	 */
-	@SuppressWarnings("unchecked")
-	public List<String> getOrderList() {
-		// Get map entry
-		return (List<String>) get(ORDER_LIST);
-	}
-	
-	
-	/**
-	 * Add order to order list
-	 */
-	@SuppressWarnings("unchecked")
-	public void addOrder(String newOrder) {
-		// Get map entry
-		((List<String>) get(ORDER_LIST)).add(newOrder);		
-	}
-	
-	
-	/**
-	 * Clear order list
-	 */
-	@SuppressWarnings("unchecked")
-	public void clearOrder() {
-		// Get map entry
-		((List<String>) get(ORDER_LIST)).clear();		
-	}
-	
 	
 	/**
 	 * Get occupation state
@@ -616,28 +494,6 @@
 		status.put(OCCUPIER, occId);
 	}
 	
-
-	/**
-	 * Get last occupier ID
-	 */
-	public String getLastOccupierID() {
-		// If member is not set, a null pointer Exception will be thrown when invoking toString(). Return an empty string in this case (=no occupier)
-		try {
-			return status.get(LAST_OCCUPIER).toString();
-		} catch (NullPointerException e) {
-			return "";
-		}
-	}
-	
-	
-	/**
-	 * Set last occupier ID
-	 */
-	public void setLastOccupierID(String occId) {
-		status.put(LAST_OCCUPIER, occId);
-	}
-	
-	
 	/**
 	 * Get execution mode
 	 */
@@ -743,26 +599,7 @@
 		// Change error state
 		status.put(ERROR_STATE, errorState);
 	}
-	
-	
-	/**
-	 * Get last error state
-	 */
-	public String getLastErrorState() {
-		// If member is not set, a null pointer Exception will be thrown when invoking toString(). Return an empty string in this case (=no occupier)
-		try {return status.get(PREV_ERROR).toString();} catch (NullPointerException e) {return "";}
-	}
-	
-	
-	/**
-	 * Set last error state
-	 */
-	public void setLastErrorState(String lastErrorState) {
-		// Change last error state
-		status.put(PREV_ERROR, lastErrorState);
-	}
-	
-	
+
 
 	/**
 	 * Get last command
@@ -780,42 +617,6 @@
 		// Change last command
 		put(CMD, cmd);		
 	}
-	
-	
-	/**
-	 * Get local overwrite variable
-	 */
-	public String getLocalOverwrite() {
-		// If member is not set, a null pointer Exception will be thrown when invoking toString(). Return an empty string in this case (=no occupier)
-		try {return get(LOCAL_OVERWRITE).toString();} catch (NullPointerException e) {return "";}
-	}
-	
-	
-	/**
-	 * Set local overwrite variable
-	 */
-	public void setLocalOverwrite(String cmd) {
-		// Change local overwrite command
-		put(LOCAL_OVERWRITE, cmd);		
-	}
-
-
-	/**
-	 * Get local overwrite free variable
-	 */
-	public String getLocalOverwriteFree() {
-		// If member is not set, a null pointer Exception will be thrown when invoking toString(). Return an empty string in this case (=no occupier)
-		try {return get(LOCAL_OVERWRITE_FREE).toString();} catch (NullPointerException e) {return "";}
-	}
-	
-	
-	/**
-	 * Set local overwrite free variable
-	 */
-	public void setLocalOverwriteFree(String cmd) {
-		// Change local overwrite free command
-		put(LOCAL_OVERWRITE_FREE, cmd);		
-	}
 }
 
 
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/models/controlcomponent/ControlComponentChangeListener.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/models/controlcomponent/ControlComponentChangeListener.java
index 682f404..e842153 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/models/controlcomponent/ControlComponentChangeListener.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/models/controlcomponent/ControlComponentChangeListener.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.models.controlcomponent;
 
 
@@ -27,14 +36,6 @@
 	 * Indicate new occupation state
 	 */
 	public void onNewOccupationState(OccupationState state);
-
-	
-	/**
-	 * Indicate a change of last occupier. This is probably not relevant for many sub classes, therefore this class
-	 * provides a default implementation. 
-	 */
-	default void onLastOccupier(String lastOccupierId) { /* Do nothing */ }
-
 		
 	/**
 	 * Indicate an execution mode change
@@ -64,12 +65,5 @@
 	 * Indicate an error state change
 	 */
 	public void onChangedErrorState(String newWorkState);
-
-	
-	/**
-	 * Indicate an previous error state change. This is probably not relevant for many sub classes, therefore this class
-	 * provides a default implementation. 
-	 */
-	default void onChangedPrevError(String newWorkState) { /* Do nothing */ }
 }
 
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/models/controlcomponent/ExecutionMode.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/models/controlcomponent/ExecutionMode.java
index 6575810..31ecadc 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/models/controlcomponent/ExecutionMode.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/models/controlcomponent/ExecutionMode.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.models.controlcomponent;
 
 
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/models/controlcomponent/ExecutionOrder.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/models/controlcomponent/ExecutionOrder.java
index 363a7c6..461958a 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/models/controlcomponent/ExecutionOrder.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/models/controlcomponent/ExecutionOrder.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.models.controlcomponent;
 
 
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/models/controlcomponent/ExecutionState.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/models/controlcomponent/ExecutionState.java
index 32301de..fbe371a 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/models/controlcomponent/ExecutionState.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/models/controlcomponent/ExecutionState.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.models.controlcomponent;
 
 
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/models/controlcomponent/OccupationState.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/models/controlcomponent/OccupationState.java
index 24dd288..09c199c 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/models/controlcomponent/OccupationState.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/models/controlcomponent/OccupationState.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.models.controlcomponent;
 
 
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/models/controlcomponent/SimpleControlComponent.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/models/controlcomponent/SimpleControlComponent.java
index ebdc938..b7caeb9 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/models/controlcomponent/SimpleControlComponent.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/models/controlcomponent/SimpleControlComponent.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.models.controlcomponent;
 
 
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/models/controlcomponent/SimpleProxyControlComponent.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/models/controlcomponent/SimpleProxyControlComponent.java
index 4d2d100..a8e2973 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/models/controlcomponent/SimpleProxyControlComponent.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/models/controlcomponent/SimpleProxyControlComponent.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.models.controlcomponent;
 
 import org.eclipse.basyx.components.netcomm.NetworkReceiver;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/support/bundle/AASBundle.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/support/bundle/AASBundle.java
index db6a3fe..78448a2 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/support/bundle/AASBundle.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/support/bundle/AASBundle.java
@@ -1,9 +1,18 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.support.bundle;
 
 import java.util.Set;
 
 import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
-import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
 
 /**
  * Helper class to bundle an AAS with its corresponding submodels, e.g. for
@@ -14,9 +23,9 @@
  */
 public class AASBundle {
 	private IAssetAdministrationShell aas;
-	private Set<ISubModel> submodels;
+	private Set<ISubmodel> submodels;
 
-	public AASBundle(IAssetAdministrationShell aas, Set<ISubModel> submodels) {
+	public AASBundle(IAssetAdministrationShell aas, Set<ISubmodel> submodels) {
 		super();
 		this.aas = aas;
 		this.submodels = submodels;
@@ -26,7 +35,7 @@
 		return aas;
 	}
 
-	public Set<ISubModel> getSubmodels() {
+	public Set<ISubmodel> getSubmodels() {
 		return submodels;
 	}
 
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/support/bundle/AASBundleDescriptorFactory.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/support/bundle/AASBundleDescriptorFactory.java
index 2291fa4..f598baf 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/support/bundle/AASBundleDescriptorFactory.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/support/bundle/AASBundleDescriptorFactory.java
@@ -1,13 +1,20 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.support.bundle;
 
 import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
 import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
-import org.eclipse.basyx.components.servlet.aas.AASBundleServlet;
 import org.eclipse.basyx.vab.modelprovider.VABPathTools;
 
 /**
- * Helper class that supports AASDescriptor utilization for an AASBundle under
- * the assumption, that is is hosted using {@link AASBundleServlet}
+ * Helper class that supports AASDescriptor utilization for an AASBundle
  * 
  * @author schnicke
  *
@@ -15,8 +22,9 @@
 public class AASBundleDescriptorFactory {
 	/**
 	 * Creates the AASDescriptor for the given bundle and hostPath
+	 * 
 	 * @param bundle
-	 * @param hostBasePath the hostBasePath the  {@link AASBundleServlet} will be hosted on
+	 * @param hostBasePath
 	 * @return
 	 */
 	public static AASDescriptor createAASDescriptor(AASBundle bundle, String hostBasePath) {
@@ -24,7 +32,9 @@
 		String nHostBasePath = VABPathTools.stripSlashes(hostBasePath);
 
 		// Create AASDescriptor
-		String aasBase = VABPathTools.concatenatePaths(nHostBasePath, bundle.getAAS().getIdShort(), "aas");
+		String endpointId = bundle.getAAS().getIdentification().getId();
+		endpointId = VABPathTools.encodePathElement(endpointId);
+		String aasBase = VABPathTools.concatenatePaths(nHostBasePath, endpointId, "aas");
 		AASDescriptor desc = new AASDescriptor(bundle.getAAS(), aasBase);
 		bundle.getSubmodels().stream().forEach(s -> {
 			SubmodelDescriptor smDesc = new SubmodelDescriptor(s, VABPathTools.concatenatePaths(aasBase, "submodels", s.getIdShort(), "submodel"));
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/support/bundle/AASBundleHelper.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/support/bundle/AASBundleHelper.java
new file mode 100644
index 0000000..f7a48fa
--- /dev/null
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/support/bundle/AASBundleHelper.java
@@ -0,0 +1,138 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.support.bundle;
+
+import java.util.Collection;
+
+import org.eclipse.basyx.aas.aggregator.api.IAASAggregator;
+import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.vab.exception.provider.ProviderException;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * This class can be used to check if all required resources are present on a server<br>
+ * (e.g. after a restart) and upload them if necessary.
+ * 
+ * @author conradi
+ *
+ */
+public class AASBundleHelper {
+	
+	private static Logger logger = LoggerFactory.getLogger(AASBundleHelper.class);
+
+	/**
+	 * Checks (by ID) if all AASs/SMs contained<br>
+	 * in the given AASBundles exist in the AASAggregator.<br>
+	 * Adds missing ones to the Aggregator.<br>
+	 * If a given object already exists in the Aggregator it will NOT be replaced.
+	 * 
+	 * @param aggregator the Aggregator to be populated
+	 * @param bundles the AASBundles
+	 * @return true if an AAS/SM was uploaded; false otherwise
+	 */
+	public static boolean integrate(IAASAggregator aggregator, Collection<AASBundle> bundles) {
+		
+		if(aggregator == null || bundles == null) {
+			throw new RuntimeException("'aggregator' and 'bundles' must not be null.");
+		}
+		
+		boolean objectUploaded = false;
+		
+		for(AASBundle bundle: bundles) {
+			IAssetAdministrationShell aas = bundle.getAAS();
+			
+			try {				
+				aggregator.getAAS(aas.getIdentification());
+				// If no ResourceNotFoundException occurs, AAS exists on server
+				// -> no further action required
+			} catch(ResourceNotFoundException e) {
+				// AAS does not exist and needs to be pushed to the server
+				// Cast Interface to concrete class
+				if(aas instanceof AssetAdministrationShell) {
+					aggregator.createAAS((AssetAdministrationShell) aas);
+					objectUploaded = true;
+				} else {
+					throw new RuntimeException("aas Objects in bundles need to be instance of 'AssetAdministrationShell'");
+				}
+			}
+			
+			IModelProvider provider = aggregator.getAASProvider(aas.getIdentification());
+			for (ISubmodel sm : bundle.getSubmodels()) {
+				try {
+					provider.getValue("/aas/submodels/" + sm.getIdShort());
+					// If no ResourceNotFoundException occurs, SM exists on server
+					// -> no further action required
+				} catch (ResourceNotFoundException e) {
+					// AAS does not exist and needs to be pushed to the server
+					// Check if ISubmodel is a concrete Submodel
+					if (sm instanceof Submodel) {
+						provider.setValue("/aas/submodels/" + sm.getIdShort(), sm);
+						objectUploaded = true;
+					} else {
+						throw new RuntimeException("sm Objects in bundles need to be instance of 'Submodel'");
+					}
+				}
+			}
+		}
+		return objectUploaded;
+	}
+	
+	/**
+	 * Registers a given set of bundles with the registry
+	 * 
+	 * @param registry
+	 *            the registry to register with
+	 * @param bundles
+	 *            the bundles to register
+	 * @param aasAggregatorPath
+	 *            the aggregator path, e.g. <i>http://localhost:4000/shells</i>
+	 */
+	public static void register(IAASRegistry registry, Collection<AASBundle> bundles, String aasAggregatorPath) {
+		bundles.stream().map(b -> AASBundleDescriptorFactory.createAASDescriptor(b, aasAggregatorPath)).forEach(registry::register);
+	}
+	
+	/**
+	 * Deregisters a given set of bundles from a given registry
+	 * 
+	 * @param registry the registry to deregister from
+	 * @param bundles the AASBundles to be deregistred
+	 */
+	public static void deregister(IAASRegistry registry, Collection<AASBundle> bundles) {
+		if(registry != null && bundles != null) {
+			for(AASBundle bundle: bundles) {
+				IAssetAdministrationShell aas = bundle.getAAS();
+				
+				try {
+					registry.delete(aas.getIdentification());
+				} catch (ProviderException e) {
+					logger.info("The AAS '" + aas.getIdShort() + "' can't be deregistered. It was not found in registry.");
+					// Just continue if deregistration failed
+				}
+				
+				for(ISubmodel sm: bundle.getSubmodels()) {
+					try {
+						registry.delete(sm.getIdentification());
+					} catch (ProviderException e) {
+						logger.info("The SM '" + sm.getIdShort() + "' can't be deregistered. It was not found in registry.");
+						// Just continue if deregistration failed
+					}
+				}
+			}
+		}
+	}
+}
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/aas/active/ActiveModel.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/aas/active/ActiveModel.java
index b072acf..de44bf5 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/aas/active/ActiveModel.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/aas/active/ActiveModel.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.tools.aas.active;
 
 import java.util.HashSet;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/aas/active/HTTPGetter.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/aas/active/HTTPGetter.java
index 7e2293b..232461a 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/aas/active/HTTPGetter.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/aas/active/HTTPGetter.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.tools.aas.active;
 
 import java.io.Serializable;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/aas/active/HTTPSupplier.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/aas/active/HTTPSupplier.java
index 4a28099..7fd75e7 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/aas/active/HTTPSupplier.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/aas/active/HTTPSupplier.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.tools.aas.active;
 
 import java.io.Serializable;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/aas/active/VABModelTask.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/aas/active/VABModelTask.java
index b629185..c1cac68 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/aas/active/VABModelTask.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/aas/active/VABModelTask.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.tools.aas.active;
 
 import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/aas/active/VABModelTaskGroup.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/aas/active/VABModelTaskGroup.java
index 5f5ed0a..88dbad6 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/aas/active/VABModelTaskGroup.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/aas/active/VABModelTaskGroup.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.tools.aas.active;
 
 import java.util.LinkedList;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sql/driver/ISQLDriver.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sql/driver/ISQLDriver.java
new file mode 100644
index 0000000..d9f8e60
--- /dev/null
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sql/driver/ISQLDriver.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.tools.sql.driver;
+
+import java.sql.ResultSet;
+
+
+
+/**
+ * Database access interface
+ * 
+ * @author kuhn
+ *
+ */
+public interface ISQLDriver {
+
+	
+	/**
+	 * Execute a SQL query
+	 */
+	public ResultSet sqlQuery(String queryString);
+
+	
+	/**
+	 * Execute a SQL update
+	 */
+	public void sqlUpdate(String updateString);
+}
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sql/driver/SQLDriver.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sql/driver/SQLDriver.java
new file mode 100644
index 0000000..36fc400
--- /dev/null
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sql/driver/SQLDriver.java
@@ -0,0 +1,233 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.tools.sql.driver;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+import javax.sql.rowset.CachedRowSet;
+import javax.sql.rowset.RowSetFactory;
+import javax.sql.rowset.RowSetProvider;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.zaxxer.hikari.HikariDataSource;
+
+
+/**
+ * Access SQL database
+ * 
+ * @author kuhn
+ *
+ */
+public class SQLDriver implements ISQLDriver {
+	private static Logger logger = LoggerFactory.getLogger(SQLDriver.class);
+
+	
+	/**
+	 * Store user name
+	 */
+	protected String userName = null;
+	
+	/**
+	 * Store password
+	 */
+	protected String password = null;
+
+	/**
+	 * Store path to database server
+	 */
+	protected String dbPath = null;
+	
+	
+	/**
+	 * Store query prefix
+	 */
+	protected String queryPrefix = null;
+	
+	
+	/**
+	 * Store driver class (with package name)
+	 */
+	protected String qualDriverClass = null;
+	
+	
+	/**
+	 * JDBC connection
+	 */
+	protected Connection connect = null;
+	
+	/**
+	 * Data source
+	 */
+	protected HikariDataSource ds = null;
+
+	
+	
+	
+	/**
+	 * Create a SQL driver and a SQL connection
+	 */
+	public SQLDriver(String path, String user, String pass, String qryPfx, String qDrvCls) {
+		// Store parameter
+		userName        = user;
+		password        = pass;
+		dbPath          = path;
+		queryPrefix     = qryPfx;
+		qualDriverClass = qDrvCls;
+		
+		// This will load the MySQL driver, each DB has its own driver
+		try {
+			Class.forName(qualDriverClass);
+		} catch (ClassNotFoundException e) {
+			logger.error("Could not init SQLDriver", e);
+		}
+	}
+	
+	
+	
+	/**
+	 * Execute a SQL query
+	 */
+	@Override
+	public CachedRowSet sqlQuery(String queryString) {
+		// Store SQL statement, flag that indicates whether the connection was created by this 
+		// operation (and needs to be closed), and result
+		Statement statement              = null;
+		CachedRowSet rowSet              = null;
+		
+		
+		// Access database
+		try {
+			// Open a connection with data source
+			openConnection();
+
+			// Statements allow to issue SQL queries to the database
+			statement = connect.createStatement();
+			
+			// ResultSet gets the result of the SQL query
+			ResultSet resultSet = statement.executeQuery(queryString);
+			
+			// Convert DB data to memory cache
+			rowSet = getCachedRowSet(resultSet);
+			
+			// Close connection with data source
+			closeConnection();
+		} catch (SQLException e) {
+			logger.error("sqlQuery failed", e);
+		}
+		
+		// Return result of query
+		return rowSet;
+	}
+	
+	
+	
+	/**
+	 * Execute a SQL update
+	 */
+	@Override
+	public void sqlUpdate(String updateString) {
+		// Store SQL statement
+		Statement statement              = null;
+		
+		// Access database
+		try {
+			// Open a connection with data source
+			openConnection();
+
+			// Statements allow to issue SQL queries to the database
+			statement = connect.createStatement();
+
+			// ResultSet gets the result of the SQL query
+			statement.executeUpdate(updateString);
+
+			// Close connection with data source
+			closeConnection();
+		} catch (SQLException e) {
+			logger.error("sqlUpdate failed", e);
+		}
+	}
+	
+	
+	
+	/**
+	 * Open connection
+	 */
+	public void openConnection() {
+		// Access database
+		try {
+			// Open connection
+			if (connect == null) {
+				openDataSource();
+				connect = ds.getConnection();
+			}
+		} catch (SQLException e) {
+			logger.error("Failed to open sql driver connection", e);
+		}
+	}
+	
+	
+	/**
+	 * Close connection
+	 */
+	public void closeConnection() {
+		// Access database
+		try {
+			// Close connection
+			if (connect != null) {
+				connect.close();
+				connect = null;
+			}
+		} catch (SQLException e) {
+			logger.error("Failed to close sql driver connection", e);
+		}
+	}
+	
+	
+	/**
+	 * Get connection
+	 */
+	public Connection getConnection() {
+		return connect;
+	}
+	
+	
+	/**
+	 * Indicate if driver has open connection
+	 */
+	public boolean hasOpenConnection() {
+		return (connect == null);
+	}
+	
+	/**
+	 * Open Data source
+	*/
+	private void openDataSource() {
+		if (ds == null) {
+			ds = new HikariDataSource();
+			ds.setJdbcUrl(queryPrefix+dbPath);
+			ds.setUsername(userName);
+			ds.setPassword(password);
+			ds.setMaximumPoolSize(5);
+		}
+	}
+	
+	private CachedRowSet getCachedRowSet(ResultSet resultSet) throws SQLException {
+		RowSetFactory factory = RowSetProvider.newFactory();
+		CachedRowSet rowset = factory.createCachedRowSet();
+		rowset.populate(resultSet);
+		return rowset;
+	}
+}
+
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sql/query/DynamicSQLOperation.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sql/query/DynamicSQLOperation.java
new file mode 100644
index 0000000..1706406
--- /dev/null
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sql/query/DynamicSQLOperation.java
@@ -0,0 +1,120 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.tools.sql.query;
+
+import java.lang.reflect.InvocationTargetException;
+import java.sql.ResultSet;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.function.Function;
+
+import org.eclipse.basyx.components.tools.propertyfile.opdef.OperationDefinition;
+import org.eclipse.basyx.components.tools.propertyfile.opdef.Parameter;
+import org.eclipse.basyx.components.tools.propertyfile.opdef.ResultFilter;
+import org.eclipse.basyx.tools.sql.driver.ISQLDriver;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+
+/**
+ * Implement a generic SQL query
+ * 
+ * @author kuhn
+ *
+ */
+public class DynamicSQLOperation extends DynamicSQLRunner implements Function<Object[], Object> {
+	private static Logger logger = LoggerFactory.getLogger(DynamicSQLOperation.class);
+
+	
+	/**
+	 * Store SQL query string with place holders ($x)
+	 */
+	protected String sqlQueryString = null;
+	
+	
+	/**
+	 * Store SQL result filter
+	 */
+	protected String resultFilterString = null;
+	
+	
+	
+	
+	
+	/**
+	 * Constructor
+	 */
+	public DynamicSQLOperation(ISQLDriver driver, String query, String sqlResultFilter) {
+		// Invoke base constructor
+		super(driver);
+		
+		// Store parameter count and SQL query string
+		sqlQueryString         = query;
+		resultFilterString     = sqlResultFilter;
+	}
+
+	
+	/**
+	 * Constructor
+	 */
+	public DynamicSQLOperation(String path, String user, String pass, String qryPfx, String qDrvCls, String query, String sqlResultFilter) {
+		// Invoke base constructor
+		super(path, user, pass, qryPfx, qDrvCls);
+		
+		// Store parameter count and SQL query string
+		sqlQueryString         = query;
+		resultFilterString     = sqlResultFilter;
+	}
+	
+	
+	/**
+	 * Execute query with given parameter
+	 */
+	@Override
+	public Object apply(Object[] parameter) {
+		// Create list of query parameter
+		Collection<String> sqlQueryParameter = new LinkedList<>();
+		// - Add parameter
+		for (Object par: parameter) sqlQueryParameter.add(par.toString());
+		
+		// Apply parameter and create SQL query string
+		String sqlQuery = OperationDefinition.getSQLString(sqlQueryString, sqlQueryParameter);
+		
+		logger.debug("Running SQL query:" + sqlQuery);
+
+		// Execute SQL query
+		ResultSet sqlResult = sqlDriver.sqlQuery(sqlQuery);
+		
+		// Extract input parameter definition
+		Collection<Parameter> resultParameter = OperationDefinition.getParameter(resultFilterString);
+
+		// Process result
+		try {
+			// Create inner parameter array for call
+			Object[] callParameterInner = new Object[resultParameter.size()];
+			int i=0; for (String column: getColumnNames(resultParameter)) callParameterInner[i++]=column;
+
+			// Create parameter array for call
+			Object[] callParameter = new Object[2];
+			callParameter[0] = sqlResult;
+			callParameter[1] = callParameterInner;
+			
+			// Invoke result filter operation using static invocation
+			return ResultFilter.class.getMethod(OperationDefinition.getOperation(resultFilterString), getMethodParameter(resultParameter)).invoke(null, callParameter);
+		} catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
+			logger.error("Could not invoke dynamic sql operation", e);
+		}
+		
+		// No result
+		return null;
+	}
+}
+
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sql/query/DynamicSQLQuery.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sql/query/DynamicSQLQuery.java
new file mode 100644
index 0000000..039c9f3
--- /dev/null
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sql/query/DynamicSQLQuery.java
@@ -0,0 +1,162 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.tools.sql.query;
+
+import java.lang.reflect.InvocationTargetException;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Collection;
+import java.util.Map;
+import java.util.function.Supplier;
+
+import org.eclipse.basyx.components.tools.propertyfile.opdef.OperationDefinition;
+import org.eclipse.basyx.components.tools.propertyfile.opdef.Parameter;
+import org.eclipse.basyx.components.tools.propertyfile.opdef.ResultFilter;
+import org.eclipse.basyx.tools.sql.driver.ISQLDriver;
+
+
+
+/**
+ * Implement a generic SQL query
+ * 
+ * @author kuhn
+ *
+ */
+public class DynamicSQLQuery extends DynamicSQLRunner implements Supplier<Object> {
+
+	
+	/**
+	 * Store SQL query string with place holders ($x)
+	 */
+	protected String sqlQueryString = null;
+	
+	
+	/**
+	 * Store SQL result filter
+	 */
+	protected String resultFilterString = null;
+	
+	
+	
+	
+	
+	/**
+	 * Constructor that accepts a driver
+	 */
+	public DynamicSQLQuery(ISQLDriver driver, String query, String sqlResultFilter) {
+		// Invoke base constructor
+		super(driver);
+
+		// Store SQL query string and result filter
+		sqlQueryString         = query;
+		resultFilterString     = sqlResultFilter;
+	}
+
+	
+	/**
+	 * Constructor
+	 */
+	public DynamicSQLQuery(String path, String user, String pass, String qryPfx, String qDrvCls, String query, String sqlResultFilter) {
+		// Invoke base constructor
+		super(path, user, pass, qryPfx, qDrvCls);
+		
+		// Store SQL query string and result filter
+		sqlQueryString         = query;
+		resultFilterString     = sqlResultFilter;
+	}
+
+	
+	/**
+	 * Execute query without parameter
+	 */
+	@Override
+	public Object get() {
+		// Execute SQL query
+		ResultSet sqlResult = sqlDriver.sqlQuery(sqlQueryString);
+
+		// Process result
+		return processResult(sqlResult);
+	}
+	
+	
+	/**
+	 * Execute query without parameter, do not post process result
+	 */
+	public ResultSet getRaw() {
+		// Execute SQL query
+		return sqlDriver.sqlQuery(sqlQueryString);
+	}
+
+	
+	/**
+	 * Execute query without parameter
+	 */
+	public Object get(Map<String,Object> param) {
+		// Apply parameter and create SQL query string
+		String sqlQuery = OperationDefinition.getSQLString(sqlQueryString, param);
+
+		// Execute SQL query
+		ResultSet sqlResult = sqlDriver.sqlQuery(sqlQuery);
+
+		// Process result
+		return processResult(sqlResult);
+	}
+
+	
+	/**
+	 * Execute query without parameter, do not post process result
+	 */
+	public ResultSet getRaw(Map<String,Object> param) {
+		// Apply parameter and create SQL query string
+		String sqlQuery = OperationDefinition.getSQLString(sqlQueryString, param);
+
+		// Execute SQL query
+		return sqlDriver.sqlQuery(sqlQuery);
+	}
+	
+	
+	
+	/**
+	 * Process result parameter
+	 */
+	protected Object processResult(ResultSet sqlResult) {
+		// Extract input parameter definition
+		Collection<Parameter> parameter = OperationDefinition.getParameter(resultFilterString);
+
+		// Process result
+		try {
+			// Create inner parameter array for call
+			Object[] callParameterInner = new Object[parameter.size()];
+			int i=0; for (String column: getColumnNames(parameter)) callParameterInner[i++]=column;
+
+			// Create parameter array for call
+			Object[] callParameter = new Object[2];
+			callParameter[0] = sqlResult;
+			callParameter[1] = callParameterInner;
+
+			// Invoke result filter operation using static invocation
+			Object result = ResultFilter.class.getMethod(OperationDefinition.getOperation(resultFilterString), getMethodParameter(parameter)).invoke(null, callParameter);
+			
+			// Close result set
+			sqlResult.close();
+			
+			// Return result
+			return result;
+			
+		} catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | SQLException e) {
+			// Print exception to console
+			e.printStackTrace();
+		}
+
+		// No result
+		return null;
+	}
+}
+
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sql/query/DynamicSQLRunner.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sql/query/DynamicSQLRunner.java
new file mode 100644
index 0000000..476bc6e
--- /dev/null
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sql/query/DynamicSQLRunner.java
@@ -0,0 +1,88 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.tools.sql.query;
+
+import java.sql.ResultSet;
+import java.util.Collection;
+import java.util.LinkedList;
+
+import org.eclipse.basyx.components.tools.propertyfile.opdef.Parameter;
+import org.eclipse.basyx.tools.sql.driver.ISQLDriver;
+import org.eclipse.basyx.tools.sql.driver.SQLDriver;
+
+
+
+
+/**
+ * SQL query operation
+ * 
+ * @author kuhn
+ *
+ */
+public class DynamicSQLRunner {
+
+	
+	/**
+	 * Store SQL driver instance
+	 */
+	protected ISQLDriver sqlDriver = null;
+	
+	
+	
+	
+	
+	/**
+	 * Constructor that accepts a driver
+	 */
+	public DynamicSQLRunner(ISQLDriver driver) {
+		// Store SQL driver instance
+		sqlDriver = driver;
+	}
+
+	
+	/**
+	 * Constructor
+	 */
+	public DynamicSQLRunner(String path, String user, String pass, String qryPfx, String qDrvCls) {
+		// Create SQL driver instance
+		sqlDriver = new SQLDriver(path, user, pass, qryPfx, qDrvCls);
+	}
+	
+	
+	
+	/**
+	 * Get method parameter definition
+	 */
+	protected Class<?>[] getMethodParameter(Collection<Parameter> parameter) {
+		// Store operation signature
+		Class<?>[] result = new Class<?>[2];
+		
+		// Operation signature is ResultSet and a list of string parameter that define column names
+		result[0] = ResultSet.class;
+		result[1] = Object[].class;
+		
+		// Return signature
+		return result;
+	}
+	
+	
+	/**
+	 * Get column names
+	 */
+	protected Collection<String> getColumnNames(Collection<Parameter> parameter) {
+		// Return value
+		Collection<String> result = new LinkedList<>();
+		
+		for (Parameter par: parameter) result.add(par.getName());
+		
+		return result;
+	}
+}
+
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sql/query/DynamicSQLUpdate.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sql/query/DynamicSQLUpdate.java
new file mode 100644
index 0000000..0160392
--- /dev/null
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sql/query/DynamicSQLUpdate.java
@@ -0,0 +1,80 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.tools.sql.query;
+
+import java.util.Map;
+import java.util.function.Consumer;
+
+import org.eclipse.basyx.components.tools.propertyfile.opdef.OperationDefinition;
+import org.eclipse.basyx.tools.sql.driver.ISQLDriver;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+
+/**
+ * Implement a generic SQL query
+ * 
+ * @author kuhn
+ *
+ */
+public class DynamicSQLUpdate extends DynamicSQLRunner implements Consumer<Map<String,Object>> {
+	private static Logger logger = LoggerFactory.getLogger(DynamicSQLUpdate.class);
+
+	/**
+	 * Store SQL query string with place holders ($x)
+	 */
+	protected String sqlQueryString = null;
+	
+	
+	
+	
+	/**
+	 * Constructor
+	 */
+	public DynamicSQLUpdate(ISQLDriver driver, String query) {
+		// Invoke base constructor
+		super(driver);
+
+		// Store parameter count and SQL query string
+		sqlQueryString         = query;
+	}
+
+	
+	/**
+	 * Constructor
+	 */
+	public DynamicSQLUpdate(String path, String user, String pass, String qryPfx, String qDrvCls, String query) {
+		// Invoke base constructor
+		super(path, user, pass, qryPfx, qDrvCls);
+		
+		// Store parameter count and SQL query string
+		sqlQueryString         = query;
+	}
+	
+
+
+	/**
+	 * Execute update with given parameter
+	 */
+	@Override
+	public void accept(Map<String,Object> parameter) {
+		logger.debug("(Parameters) Running SQL update: " + parameter);
+
+		// Apply parameter and create SQL query string
+		String sqlQuery = OperationDefinition.getSQLString(sqlQueryString, parameter);
+		
+		logger.debug("(Query) Running SQL update:" + sqlQuery);
+
+		// Execute SQL query
+		sqlDriver.sqlUpdate(sqlQuery);
+	}
+}
+
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sqlproxy/SQLCollection.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sqlproxy/SQLCollection.java
index 0a1f9b2..be67a61 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sqlproxy/SQLCollection.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sqlproxy/SQLCollection.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.tools.sqlproxy;
 
 import java.lang.reflect.Array;
@@ -9,9 +18,9 @@
 import java.util.List;
 import java.util.Map;
 
-import org.eclipse.basyx.components.sqlprovider.driver.ISQLDriver;
-import org.eclipse.basyx.components.sqlprovider.query.DynamicSQLQuery;
-import org.eclipse.basyx.components.sqlprovider.query.DynamicSQLUpdate;
+import org.eclipse.basyx.tools.sql.driver.ISQLDriver;
+import org.eclipse.basyx.tools.sql.query.DynamicSQLQuery;
+import org.eclipse.basyx.tools.sql.query.DynamicSQLUpdate;
 
 
 
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sqlproxy/SQLConnector.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sqlproxy/SQLConnector.java
index d4a113a..bb4f086 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sqlproxy/SQLConnector.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sqlproxy/SQLConnector.java
@@ -1,7 +1,16 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.tools.sqlproxy;
 
-import org.eclipse.basyx.components.sqlprovider.driver.ISQLDriver;
-import org.eclipse.basyx.components.sqlprovider.driver.SQLDriver;
+import org.eclipse.basyx.tools.sql.driver.ISQLDriver;
+import org.eclipse.basyx.tools.sql.driver.SQLDriver;
 
 /**
  * Base class for classes that connect to SQL databases
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sqlproxy/SQLMap.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sqlproxy/SQLMap.java
index 846282b..ca2f8ed 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sqlproxy/SQLMap.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sqlproxy/SQLMap.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.tools.sqlproxy;
 
 import java.sql.ResultSet;
@@ -10,9 +19,9 @@
 import java.util.Map;
 import java.util.Set;
 
-import org.eclipse.basyx.components.sqlprovider.driver.ISQLDriver;
-import org.eclipse.basyx.components.sqlprovider.query.DynamicSQLQuery;
-import org.eclipse.basyx.components.sqlprovider.query.DynamicSQLUpdate;
+import org.eclipse.basyx.tools.sql.driver.ISQLDriver;
+import org.eclipse.basyx.tools.sql.query.DynamicSQLQuery;
+import org.eclipse.basyx.tools.sql.query.DynamicSQLUpdate;
 
 
 
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sqlproxy/SQLProxy.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sqlproxy/SQLProxy.java
index 3ad7f8b..f517e36 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sqlproxy/SQLProxy.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sqlproxy/SQLProxy.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.tools.sqlproxy;
 
 import java.sql.ResultSet;
@@ -7,9 +16,9 @@
 import java.util.Map;
 import java.util.Set;
 
-import org.eclipse.basyx.components.sqlprovider.driver.ISQLDriver;
-import org.eclipse.basyx.components.sqlprovider.query.DynamicSQLQuery;
-import org.eclipse.basyx.components.sqlprovider.query.DynamicSQLUpdate;
+import org.eclipse.basyx.tools.sql.driver.ISQLDriver;
+import org.eclipse.basyx.tools.sql.query.DynamicSQLQuery;
+import org.eclipse.basyx.tools.sql.query.DynamicSQLUpdate;
 
 
 
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sqlproxy/SQLRootElement.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sqlproxy/SQLRootElement.java
index c0e0024..fb04c06 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sqlproxy/SQLRootElement.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sqlproxy/SQLRootElement.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.tools.sqlproxy;
 
 import java.util.Collection;
@@ -6,8 +15,8 @@
 import java.util.Set;
 import java.util.stream.Collectors;
 
-import org.eclipse.basyx.components.sqlprovider.query.DynamicSQLQuery;
-import org.eclipse.basyx.components.sqlprovider.query.DynamicSQLUpdate;
+import org.eclipse.basyx.tools.sql.query.DynamicSQLQuery;
+import org.eclipse.basyx.tools.sql.query.DynamicSQLUpdate;
 
 
 
@@ -38,7 +47,7 @@
 	/**
 	 * Creates the root table if it does not exist (including a possibly missing schema)
 	 */
-	public void create() {
+	public void createRootTableIfNotExists() {
 		createSchema();
 		createRootTable();
 	}
@@ -54,38 +63,41 @@
 	/**
 	 * Get next free identifier for another element
 	 */
-	@SuppressWarnings("unchecked")
 	public int getNextIdentifier() {
-		// Element ID
-		int elementID = -1;
+		Map<String, Object> sqlResult = readCurrentElementPointer();
 
+		// Store element ID
+		int elementId = Integer.parseInt((String) sqlResult.get("NextElementID"));
+
+		// SQL update statement
+		String updateString = "UPDATE elements." + getSqlTableID() + " SET NextElementID='" + (elementId + 1)
+				+ "', ElementPrefix='" + sqlResult.get("ElementPrefix") + "'";
+		DynamicSQLUpdate dynUpdate = new DynamicSQLUpdate(getDriver(), updateString);
+
+		// Empty parameter set
+		Map<String, Object> parameter = new HashMap<>();
+
+		// Execute SQL statement
+		dynUpdate.accept(parameter);
+
+		// Return element ID
+		return elementId;
+	}
+
+	@SuppressWarnings("unchecked")
+	private Map<String, Object> readCurrentElementPointer() {
 		// SQL query string
-		String queryString = "SELECT * FROM elements."+getSqlTableID();
-		DynamicSQLQuery dynQuery = new DynamicSQLQuery(getDriver(), queryString, "mapArray(NextElementID:Integer,ElementPrefix:String)");
+		String queryString = "SELECT * FROM elements." + getSqlTableID();
+		DynamicSQLQuery dynQuery = new DynamicSQLQuery(getDriver(), queryString,
+				"mapArray(NextElementID:Integer,ElementPrefix:String)");
 		
 		// Empty parameter set
 		Map<String, Object> parameter = new HashMap<>();
-		// - Execute query, return the column as 
-		Map<String, Object> sqlResult = (Map<String, Object>) dynQuery.get(parameter);
-
-		// Store element ID
-		elementID = Integer.parseInt((String) sqlResult.get("NextElementID"));
-
-		
-		// SQL update statement
-		String updateString = "UPDATE elements."+getSqlTableID()+" SET NextElementID='"+(elementID+1)+"', ElementPrefix='"+sqlResult.get("ElementPrefix")+"'";
-		DynamicSQLUpdate dynUpdate = new DynamicSQLUpdate(getDriver(), updateString);
-		
-		// Empty parameter set
-		parameter.clear();
-		
-		// Execute SQL statement
-		dynUpdate.accept(parameter);
-		
-		// Return element ID
-		return elementID;
+		// - Execute query, return the column as
+		return (Map<String, Object>) dynQuery.get(parameter);
 	}
 	
+
 	/**
 	 * Creates a schema for the root element
 	 */
@@ -131,16 +143,20 @@
 		// Execute SQL statement
 		dynCmd.accept(parameter);
 		
+		Map<String, Object> currentPointer = readCurrentElementPointer();
 		
-		// Initially fill table
-		String sqlInsertString = "INSERT INTO elements."+ getSqlTableID() +" (NextElementID, ElementPrefix) VALUES ('1', '"+getSqlTableID()+":')";
-		DynamicSQLUpdate dynUpdate = new DynamicSQLUpdate(getDriver(), sqlInsertString);
+		if (!currentPointer.containsKey("NextElementID")) {
+			// Initially fill table if it is empty
+			String sqlInsertString = "INSERT INTO elements." + getSqlTableID()
+					+ " (NextElementID, ElementPrefix) VALUES ('1', '" + getSqlTableID() + ":')";
+			DynamicSQLUpdate dynUpdate = new DynamicSQLUpdate(getDriver(), sqlInsertString);
 
-		// Clear parameter
-		parameter.clear();
-		
-		// Run SQL operation
-		dynUpdate.accept(parameter);
+			// Clear parameter
+			parameter.clear();
+
+			// Run SQL operation
+			dynUpdate.accept(parameter);
+		}
 	}
 
 	
@@ -231,5 +247,23 @@
 		// Execute SQL statement
 		dynCmd.accept(parameter);		
 	}
+
+	/**
+	 * Creates a new root map, if it does not exist. Otherwise, returns
+	 * the first map within this root element.
+	 * 
+	 * @return
+	 */
+	public SQLMap retrieveRootMap() {
+		Map<String, Object> currentPointer = readCurrentElementPointer();
+		int elementId = Integer.parseInt((String) currentPointer.get("NextElementID"));
+		if (elementId == 1) {
+			// No element has been created, yet => create new root map
+			return createMap(getNextIdentifier());
+		} else {
+			// Root map already exists => return first
+			return new SQLMap(this, 1);
+		}
+	}
 }
 
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sqlproxy/SQLTableRow.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sqlproxy/SQLTableRow.java
index c722968..5dc64d9 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sqlproxy/SQLTableRow.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sqlproxy/SQLTableRow.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.tools.sqlproxy;
 
 import java.io.ByteArrayInputStream;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sqlproxy/exception/UnknownElementTypeException.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sqlproxy/exception/UnknownElementTypeException.java
index c127ad5..ae59d25 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sqlproxy/exception/UnknownElementTypeException.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sqlproxy/exception/UnknownElementTypeException.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.tools.sqlproxy.exception;
 
 
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/webserviceclient/WebServiceJSONClient.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/webserviceclient/WebServiceJSONClient.java
index 6e1e528..dd1aa4f 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/webserviceclient/WebServiceJSONClient.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/webserviceclient/WebServiceJSONClient.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.tools.webserviceclient;
 
 import java.util.ArrayList;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/webserviceclient/WebServiceRawClient.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/webserviceclient/WebServiceRawClient.java
index 2a8f760..d1cb6b3 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/webserviceclient/WebServiceRawClient.java
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/webserviceclient/WebServiceRawClient.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.tools.webserviceclient;
 
 import java.io.Serializable;
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/cfgprovider/TestCFGProvider.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/cfgprovider/TestCFGProvider.java
deleted file mode 100644
index 655af40..0000000
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/cfgprovider/TestCFGProvider.java
+++ /dev/null
@@ -1,68 +0,0 @@
-package org.eclipse.basyx.regression.cfgprovider;
-
-import static org.junit.Assert.assertEquals;
-
-import java.util.Map;
-
-import org.eclipse.basyx.regression.support.directory.ComponentsTestsuiteDirectory;
-import org.eclipse.basyx.regression.support.server.context.ComponentsRegressionContext;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
-import org.eclipse.basyx.testsuite.regression.vab.protocol.http.AASHTTPServerResource;
-import org.eclipse.basyx.vab.manager.VABConnectionManager;
-import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
-import org.junit.ClassRule;
-import org.junit.Test;
-
-
-/**
- * Test queries to CFG file provider
- * 
- * @author kuhn
- *
- */
-public class TestCFGProvider {
-
-	
-	/**
-	 * VAB connection manager backend
-	 */
-	protected VABConnectionManager connManager = new VABConnectionManager(new ComponentsTestsuiteDirectory(), new HTTPConnectorProvider());
-
-
-	/** 
-	 * Makes sure Tomcat Server is started with basyx.components regression test case
-	 */
-	@ClassRule
-	public static AASHTTPServerResource res = new AASHTTPServerResource(new ComponentsRegressionContext());
-	
-	
-	/**
-	 * Test basic queries
-	 */
-	@SuppressWarnings("unchecked")
-	@Test
-	public void test() throws Exception {
-		// Connect to sub model "CfgFileTestAAS"
-		VABElementProxy connSubModel = this.connManager.connectToVABElement("CfgFileTestAAS");
-
-		
-		// Get property value
-		Map<String, Object> value1 = (Map<String, Object>) connSubModel
-				.getModelPropertyValue("/aas/submodels/sampleCFG/" + SubmodelElementProvider.PROPERTIES + "/cfgProperty1/value");
-
-		assertEquals("exampleStringValue", value1.get(Property.VALUE));
-
-		
-		// Get property value
-		Map<String, Object> value2 = (Map<String, Object>) connSubModel
-				.getModelPropertyValue("/aas/submodels/sampleCFG/" + SubmodelElementProvider.PROPERTIES + "/cfgProperty2/value");
-		assertEquals("12", value2.get(Property.VALUE));
-
-		// Get property value
-		Map<String, Object> value3 = (Map<String, Object>) connSubModel
-				.getModelPropertyValue("/aas/submodels/sampleCFG/" + SubmodelElementProvider.PROPERTIES + "/cfgProperty3/value");
-		assertEquals("45.8", value3.get(Property.VALUE));
-	}
-}
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/cfgprovider/TestCFGProviderPropertyMetaData.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/cfgprovider/TestCFGProviderPropertyMetaData.java
deleted file mode 100644
index 4af91ac..0000000
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/cfgprovider/TestCFGProviderPropertyMetaData.java
+++ /dev/null
@@ -1,75 +0,0 @@
-package org.eclipse.basyx.regression.cfgprovider;
-
-import static org.junit.Assert.assertEquals;
-
-import java.util.Collection;
-import java.util.Map;
-
-import org.eclipse.basyx.regression.support.directory.ComponentsTestsuiteDirectory;
-import org.eclipse.basyx.regression.support.server.context.ComponentsRegressionContext;
-import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangStrings;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
-import org.eclipse.basyx.testsuite.regression.vab.protocol.http.AASHTTPServerResource;
-import org.eclipse.basyx.vab.manager.VABConnectionManager;
-import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
-import org.junit.ClassRule;
-import org.junit.Test;
-
-/**
- * Test queries to CFG file provider
- * 
- * @author kuhn
- *
- */
-public class TestCFGProviderPropertyMetaData {
-
-	/**
-	 * VAB connection manager backend
-	 */
-	protected VABConnectionManager connManager = new VABConnectionManager(new ComponentsTestsuiteDirectory(),
-			new HTTPConnectorProvider());
-
-	/**
-	 * Makes sure Tomcat Server is started
-	 */
-	@ClassRule
-	public static AASHTTPServerResource res = new AASHTTPServerResource(new ComponentsRegressionContext());
-
-	/**
-	 * Test basic queries
-	 */
-	@SuppressWarnings("unchecked")
-	@Test
-	public void test() throws Exception {
-
-		// Connect to sub model "CfgFileTestAAS"
-		VABElementProxy connSubModel = this.connManager.connectToVABElement("CfgFileTestAAS");
-
-		// Get property value
-		Map<String, Object> value1 = (Map<String, Object>) connSubModel
-				.getModelPropertyValue("/aas/submodels/sampleCFG/" + SubmodelElementProvider.PROPERTIES + "/cfgProperty1");
-		assertEquals("exampleStringValue", value1.get(Property.VALUE));
-		// - Check property meta data (description)
-		Map<String, Object> value1a = (Map<String, Object>) connSubModel
-				.getModelPropertyValue("/aas/submodels/sampleCFG/" + SubmodelElementProvider.PROPERTIES + "/cfgProperty1");
-		LangStrings description = LangStrings.createAsFacade((Collection<Map<String, Object>>) value1a.get("description"));
-		assertEquals("Configuration property description", description.get(""));
-
-		// Get property value
-		Map<String, Object> value2 = (Map<String, Object>) connSubModel
-				.getModelPropertyValue("/aas/submodels/sampleCFG/" + SubmodelElementProvider.PROPERTIES + "/cfgProperty2");
-		assertEquals("12", value2.get(Property.VALUE));
-		// - Check property meta data (description)
-		Map<String, Object> value2a = (Map<String, Object>) connSubModel
-				.getModelPropertyValue("/aas/submodels/sampleCFG/" + SubmodelElementProvider.PROPERTIES + "/cfgProperty2");
-		description = LangStrings.createAsFacade((Collection<Map<String, Object>>) value2a.get("description"));
-		assertEquals("Configuration property description on multiple lines", description.get(""));
-
-		// Get property value
-		Map<String, Object> value3 = (Map<String, Object>) connSubModel
-				.getModelPropertyValue("/aas/submodels/sampleCFG/" + SubmodelElementProvider.PROPERTIES + "/cfgProperty3");
-		assertEquals("45.8", value3.get(Property.VALUE));
-	}
-}
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/cfgprovider/TestCFGProviderSubmodelMetaData.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/cfgprovider/TestCFGProviderSubmodelMetaData.java
deleted file mode 100644
index d38a7de..0000000
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/cfgprovider/TestCFGProviderSubmodelMetaData.java
+++ /dev/null
@@ -1,68 +0,0 @@
-package org.eclipse.basyx.regression.cfgprovider;
-
-import static org.junit.Assert.assertEquals;
-
-import java.util.Collection;
-import java.util.Map;
-
-import org.eclipse.basyx.regression.support.directory.ComponentsTestsuiteDirectory;
-import org.eclipse.basyx.regression.support.server.context.ComponentsRegressionContext;
-import org.eclipse.basyx.submodel.metamodel.map.qualifier.AdministrativeInformation;
-import org.eclipse.basyx.submodel.metamodel.map.qualifier.Identifiable;
-import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangStrings;
-import org.eclipse.basyx.testsuite.regression.vab.protocol.http.AASHTTPServerResource;
-import org.eclipse.basyx.vab.manager.VABConnectionManager;
-import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
-import org.junit.ClassRule;
-import org.junit.Test;
-
-
-
-/**
- * Test queries to CFG file provider
- * 
- * @author kuhn
- *
- */
-public class TestCFGProviderSubmodelMetaData {
-
-	
-	/**
-	 * VAB connection manager backend
-	 */
-	protected VABConnectionManager connManager = new VABConnectionManager(new ComponentsTestsuiteDirectory(), new HTTPConnectorProvider());
-
-	/** 
-	 * Makes sure Tomcat Server is started
-	 */
-	@ClassRule
-	public static AASHTTPServerResource res = new AASHTTPServerResource(new ComponentsRegressionContext());
-	
-	/**
-	 * Test basic queries
-	 */
-	@SuppressWarnings("unchecked")
-	@Test
-	public void test() throws Exception {
-
-		// Connect to sub model "CfgFileTestAAS"
-		VABElementProxy connSubModel = this.connManager.connectToVABElement("CfgFileTestAAS");
-
-		
-		// Get property value
-		Map<String, Object> sampleCFG = (Map<String, Object>) connSubModel
-				.getModelPropertyValue("/aas/submodels/sampleCFG");
-		
-		LangStrings description = LangStrings.createAsFacade((Collection<Map<String, Object>>) sampleCFG.get("description"));
-		assertEquals("BaSys regression test file for CFG file provider", description.get(""));
-
-		// Get property value
-		assertEquals("1.0",
-				AdministrativeInformation.createAsFacade((Map<String, Object>) sampleCFG.get(Identifiable.ADMINISTRATION))
-				.getVersion());
-
-		// Get complete sub model
-		Object value3 = connSubModel.getModelPropertyValue("/aas/submodels/sampleCFG");
-	}
-}
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/directory/file/TestAASDirectoryEntry.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/directory/file/TestAASDirectoryEntry.java
deleted file mode 100644
index 662b48f..0000000
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/directory/file/TestAASDirectoryEntry.java
+++ /dev/null
@@ -1,217 +0,0 @@
-package org.eclipse.basyx.regression.directory.file;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import org.eclipse.basyx.components.directory.AASDirectoryEntry;
-import org.junit.Test;
-
-
-
-/**
- * Test the AAS Directory entry class
- * 
- * @author kuhn
- *
- */
-public class TestAASDirectoryEntry {
-
-	
-	
-	/**
-	 * Execute test case that tests parsing of id constructor parameter
-	 */
-	@Test
-	public void testConstuctorParameterID() {
-		// Test object with minimal ID
-		AASDirectoryEntry aasEntry1 = new AASDirectoryEntry("urn:FHG", "<serializedAAS>", "local", "");
-		// - Validate object
-		assertTrue(aasEntry1.isValidID());
-		assertTrue(aasEntry1.getLegalEntity().equals("FHG"));
-		assertTrue(aasEntry1.isLegalEntityOf("FHG"));
-		assertFalse(aasEntry1.hasSubUnit());
-		assertFalse(aasEntry1.hasSubModel());
-		assertFalse(aasEntry1.hasVersion());
-		assertFalse(aasEntry1.hasRevision());
-		
-		
-		// Test object with empty ID, SubUnit and sub model
-		AASDirectoryEntry aasEntry2 = new AASDirectoryEntry("urn:::::", "<serializedAAS>", "local", "");
-		// - Validate object
-		assertTrue(aasEntry2.isValidID());
-		assertFalse(aasEntry2.hasLegalEntity());
-		assertFalse(aasEntry2.hasSubUnit());
-		assertFalse(aasEntry2.hasSubModel());
-		assertFalse(aasEntry2.hasVersion());
-		assertFalse(aasEntry2.hasRevision());
-
-		
-		// Test object with almost empty ID and SubUnit
-		AASDirectoryEntry aasEntry3 = new AASDirectoryEntry("urn: : : : : ", "<serializedAAS>", "local", "");
-		// - Validate object
-		assertTrue(aasEntry3.isValidID());
-		assertFalse(aasEntry3.hasLegalEntity());
-		assertFalse(aasEntry3.hasSubUnit());
-		assertFalse(aasEntry3.hasSubModel());
-		assertFalse(aasEntry3.hasVersion());
-		assertFalse(aasEntry3.hasRevision());
-
-		
-		// Test object with ID, SubUnit, version and revision
-		AASDirectoryEntry aasEntry4 = new AASDirectoryEntry("urn:FHG:iese:aas:0.97:1", "<serializedAAS>", "local", "");
-		// - Validate object
-		assertTrue(aasEntry4.isValidID());
-		assertTrue(aasEntry4.getLegalEntity().equals("FHG"));
-		assertTrue(aasEntry4.isLegalEntityOf("FHG"));
-		assertTrue(aasEntry4.hasSubUnit());
-		assertTrue(aasEntry4.getSubUnit().equals("iese"));
-		assertTrue(aasEntry4.hasSubModel());
-		assertTrue(aasEntry4.getSubModel().equals("aas"));
-		assertTrue(aasEntry4.hasVersion());
-		assertTrue(aasEntry4.getVersion().equals("0.97"));
-		assertTrue(aasEntry4.hasRevision());
-		assertTrue(aasEntry4.getRevision().equals("1"));
-		assertFalse(aasEntry4.hasElementID());
-
-		
-		// Test object with ID, SubUnit, version and revision
-		AASDirectoryEntry aasEntry5 = new AASDirectoryEntry("urn:FHG:iese:aas:0.97:1:entity", "<serializedAAS>", "local", "");
-		// - Validate object
-		assertTrue(aasEntry5.isValidID());
-		assertTrue(aasEntry5.getLegalEntity().equals("FHG"));
-		assertTrue(aasEntry5.isLegalEntityOf("FHG"));
-		assertTrue(aasEntry5.hasSubUnit());
-		assertTrue(aasEntry5.getSubUnit().equals("iese"));
-		assertTrue(aasEntry5.hasSubModel());
-		assertTrue(aasEntry5.getSubModel().equals("aas"));
-		assertTrue(aasEntry5.hasVersion());
-		assertTrue(aasEntry5.getVersion().equals("0.97"));
-		assertTrue(aasEntry5.hasRevision());
-		assertTrue(aasEntry5.getRevision().equals("1"));
-		assertTrue(aasEntry5.hasElementID());
-		assertTrue(aasEntry5.getElementID().equals("entity"));
-
-		
-		// Test object with ID, SubUnit, version and revision
-		AASDirectoryEntry aasEntry6 = new AASDirectoryEntry("urn:FHG:iese:aas:0.97:1:entity#001", "<serializedAAS>", "local", "");
-		// - Validate object
-		assertTrue(aasEntry6.isValidID());
-		assertTrue(aasEntry6.getLegalEntity().equals("FHG"));
-		assertTrue(aasEntry6.isLegalEntityOf("FHG"));
-		assertTrue(aasEntry6.hasSubUnit());
-		assertTrue(aasEntry6.getSubUnit().equals("iese"));
-		assertTrue(aasEntry6.hasSubModel());
-		assertTrue(aasEntry6.getSubModel().equals("aas"));
-		assertTrue(aasEntry6.hasVersion());
-		assertTrue(aasEntry6.getVersion().equals("0.97"));
-		assertTrue(aasEntry6.hasRevision());
-		assertTrue(aasEntry6.getRevision().equals("1"));
-		assertTrue(aasEntry6.hasElementID());
-		assertTrue(aasEntry6.getElementID().equals("entity"));
-		assertTrue(aasEntry6.hasElementInstance());
-		assertTrue(aasEntry6.getElementInstance().equals("001"));
-
-		
-		// Test object with ID, SubUnit, version and revision
-		AASDirectoryEntry aasEntry7 = new AASDirectoryEntry("urn:FHG:iese:aas:0.97:1:#001", "<serializedAAS>", "local", "");
-		// - Validate object
-		assertTrue(aasEntry7.isValidID());
-		assertTrue(aasEntry7.getLegalEntity().equals("FHG"));
-		assertTrue(aasEntry7.isLegalEntityOf("FHG"));
-		assertTrue(aasEntry7.hasSubUnit());
-		assertTrue(aasEntry7.getSubUnit().equals("iese"));
-		assertTrue(aasEntry7.hasSubModel());
-		assertTrue(aasEntry7.getSubModel().equals("aas"));
-		assertTrue(aasEntry7.hasVersion());
-		assertTrue(aasEntry7.getVersion().equals("0.97"));
-		assertTrue(aasEntry7.hasRevision());
-		assertTrue(aasEntry7.getRevision().equals("1"));
-		assertFalse(aasEntry7.hasElementID());
-		assertTrue(aasEntry7.hasElementInstance());
-		assertTrue(aasEntry7.getElementInstance().equals("001"));
-	}
-
-	
-	
-	/**
-	 * Execute test case that tests parsing of content and content type constructor parameter
-	 */
-	@Test
-	public void testConstuctorParameterContentAndContentType() {
-		// Test object with local content and without tags
-		AASDirectoryEntry aasEntry1 = new AASDirectoryEntry("urn:FHG:iese:aas:0.97:1:#001", "<serializedAAS>", "local", "");
-		// - Validate object
-		assertTrue(aasEntry1.getAASContent().equals("<serializedAAS>"));
-		assertTrue(aasEntry1.getAASContentType() == AASDirectoryEntry.AAS_CONTENTTYPE_LOCAL);
-		assertTrue(aasEntry1.getAASTags().isEmpty());
-		
-		
-		// Test object with remote content and without tags
-		AASDirectoryEntry aasEntry2 = new AASDirectoryEntry("urn:FHG:iese:aas:0.97:1:#001", "<serializedAAS>", "remote", "");
-		// - Validate object
-		assertTrue(aasEntry2.getAASContent().equals("<serializedAAS>"));
-		assertTrue(aasEntry2.getAASContentType() == AASDirectoryEntry.AAS_CONTENTTYPE_REMOTE);
-		assertTrue(aasEntry2.getAASTags().isEmpty());
-
-		
-		// Test object with remote content and without tags
-		AASDirectoryEntry aasEntry3 = new AASDirectoryEntry("urn:FHG:iese:aas:0.97:1:#001", "<serializedAAS>", "ReMote", "");
-		// - Validate object
-		assertTrue(aasEntry3.getAASContent().equals("<serializedAAS>"));
-		assertTrue(aasEntry3.getAASContentType() == AASDirectoryEntry.AAS_CONTENTTYPE_REMOTE);
-		assertTrue(aasEntry3.getAASTags().isEmpty());
-
-		
-		// Test object with proxy content and without tags
-		AASDirectoryEntry aasEntry4 = new AASDirectoryEntry("urn:FHG:iese:aas:0.97:1:#001", "<serializedAAS>", "PROXY", "");
-		// - Validate object
-		assertTrue(aasEntry4.getAASContent().equals("<serializedAAS>"));
-		assertTrue(aasEntry4.getAASContentType() == AASDirectoryEntry.AAS_CONTENTTYPE_PROXY);
-		assertTrue(aasEntry4.getAASTags().isEmpty());
-	}
-
-	
-	
-	/**
-	 * Execute test case that tests parsing of tags constructor parameter
-	 */
-	@Test
-	public void testConstuctorParameterTags() {
-		// Test object without tags
-		AASDirectoryEntry aasEntry1 = new AASDirectoryEntry("urn:FHG:iese:aas:0.97:1:#001", "<serializedAAS>", "local", "");
-		// - Validate object
-		assertTrue(aasEntry1.getAASTags().isEmpty());
-		
-		
-		// Test object with one tag
-		AASDirectoryEntry aasEntry2 = new AASDirectoryEntry("urn:FHG:iese:aas:0.97:1:#001", "<serializedAAS>", "local", "tag1");
-		// - Validate object
-		assertTrue(aasEntry2.getAASTags().size() == 1);
-		assertTrue(aasEntry2.getAASTags().toArray(new String[1])[0].equals("tag1"));
-
-		
-		// Test object with one tag
-		AASDirectoryEntry aasEntry3 = new AASDirectoryEntry("urn:FHG:iese:aas:0.97:1:#001", "<serializedAAS>", "local", "tag1,tag2");
-		// - Validate object
-		assertTrue(aasEntry3.getAASTags().size() == 2);
-		assertTrue(aasEntry3.getAASTags().toArray(new String[2])[0].equals("tag1"));
-		assertTrue(aasEntry3.getAASTags().toArray(new String[2])[1].equals("tag2"));
-	}
-
-	
-	
-	/**
-	 * Execute test case that tests invalid directory entries
-	 */
-	@Test
-	public void testInvalidConstuctorParameter() {
-		// Test object with minimal ID
-		AASDirectoryEntry aasEntry1 = new AASDirectoryEntry("FHG", "<serializedAAS>", "local", "");
-		// - Validate object
-		assertFalse(aasEntry1.isValidID());
-		assertFalse(aasEntry1.hasLegalEntity());
-		assertFalse(aasEntry1.hasSubUnit());
-		assertFalse(aasEntry1.hasSubModel());
-	}
-}
-
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/directory/file/TestStaticDirectoryFileProvider.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/directory/file/TestStaticDirectoryFileProvider.java
deleted file mode 100644
index 9449904..0000000
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/directory/file/TestStaticDirectoryFileProvider.java
+++ /dev/null
@@ -1,142 +0,0 @@
-package org.eclipse.basyx.regression.directory.file;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.io.UnsupportedEncodingException;
-import java.net.URLEncoder;
-
-import org.eclipse.basyx.regression.support.server.context.ComponentsRegressionContext;
-import org.eclipse.basyx.testsuite.regression.vab.protocol.http.AASHTTPServerResource;
-import org.eclipse.basyx.tools.webserviceclient.WebServiceRawClient;
-import org.eclipse.basyx.vab.coder.json.metaprotocol.MetaprotocolHandler;
-import org.junit.ClassRule;
-import org.junit.Test;
-
-
-
-
-/**
- * Test queries to CFG file directory provider
- * 
- * @author kuhn
- *
- */
-public class TestStaticDirectoryFileProvider {
-
-	/** 
-	 * Makes sure Tomcat Server is started
-	 */
-	@ClassRule
-	public static AASHTTPServerResource res = new AASHTTPServerResource(new ComponentsRegressionContext());
-	private MetaprotocolHandler handler = new MetaprotocolHandler();
-
-	/**
-	 * Execute test case that test working calls
-	 */
-	@Test
-	public void testWorkingCalls() {
-		// Invoke BaSyx service calls via web services
-		WebServiceRawClient client = new WebServiceRawClient();
-		
-		// Directory web service URL
-		String wsURL = "http://localhost:8080/basys.components/Testsuite/Directory/CFGFile";
-		
-		
-		// First test - get all locally registered AAS
-		{
-			// Get all locally registered AAS
-			String result = getResult(client.get(wsURL + "/api/v1/registry"));
-
-			// Check if all AAS are contained in result
-			assertTrue(result.contains("{content.aas1}"));
-			assertTrue(result.contains("{content.aas2}"));
-			assertTrue(result.contains("{content.aas3}"));
-			assertTrue(result.contains("{content.aas4}"));
-		}
-		
-		
-		// Get a specific AAS (1)
-		try {
-			// Get a known AAS by its ID
-			String result = getResult(client.get(wsURL + "/api/v1/registry/urn:de.FHG:es.iese:aas:0.98:5:lab/" + URLEncoder.encode("microscope#A-19", "UTF-8")));
-
-			// Check if all AAS are contained in result
-			assertTrue(result.equals("{content.aas1}"));
-		} catch (Exception e) {
-			fail("Get specific AAS test case did throw exception:"+e);
-		}
-
-		
-		// Get a specific AAS (2)
-		try {
-			// Get a known AAS by its ID
-			String result = getResult(client.get(wsURL + "/api/v1/registry/urn:de.FHG:es.iese:aas:0.98:5:lab/" + URLEncoder.encode("microscope#A-18", "UTF-8")));
-
-			// Check if all AAS are contained in result
-			assertTrue(result.equals("{content.aas2}"));
-		} catch (Exception e) {
-			fail("Get specific AAS test case did throw exception:"+e);
-		}
-
-		
-		// Get a specific AAS (3)
-		try {
-			// Get a known AAS by its ID
-			String result = getResult(client.get(wsURL + "/api/v1/registry/urn:de.FHG:es.iese:aas:0.98:5:lab/" + URLEncoder.encode("microscope#A-17", "UTF-8")));
-
-			// Check if all AAS are contained in result
-			assertTrue(result.equals("{content.aas3}"));
-		} catch (Exception e) {
-			fail("Get specific AAS test case did throw exception:"+e);
-		}
-
-		
-		// Get a specific AAS (4)
-		try {
-			// Get a known AAS by its ID
-			String result = getResult(client.get(wsURL + "/api/v1/registry/urn:de.FHG:es.iese:aas:0.98:5:lab/" + URLEncoder.encode("microscope#A-16", "UTF-8")));
-
-			// Check if all AAS are contained in result
-			assertTrue(result.equals("{content.aas4}"));
-		} catch (Exception e) {
-			fail("Get specific AAS test case did throw exception:"+e);
-		}
-	}
-	
-	
-	
-	/**
-	 * Execute test case that test non-working calls
-	 * 
-	 * @throws UnsupportedEncodingException
-	 */
-	@Test
-	public void testNonWorkingCalls() throws UnsupportedEncodingException {
-		// Invoke service call via web services
-		WebServiceRawClient client = new WebServiceRawClient();
-		
-		// Directory web service URL
-		String wsURL = "http://localhost:8080/basys.components/Testsuite/Directory/CFGFile";
-
-		
-		// Get unknown AAS ID
-		// Get a known AAS by its ID
-		String result = getResult(client.get(
-				wsURL + "/api/v1/registry/urn:de.FHG:es.iese:aas:0.98:5:lab/" + URLEncoder.encode("unknown", "UTF-8")));
-
-		// Check if the getting a non existing URL returns a null
-		assertEquals(null, result);
-	}
-
-	private String getResult(String res) {
-		try {
-			return (String) handler.deserialize(res);
-		} catch (Exception e) {
-			throw new RuntimeException(e);
-		}
-	}
-}
-
-
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/directory/file/TestStaticDirectoryFileProviderExceptions.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/directory/file/TestStaticDirectoryFileProviderExceptions.java
deleted file mode 100644
index 54e4749..0000000
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/directory/file/TestStaticDirectoryFileProviderExceptions.java
+++ /dev/null
@@ -1,91 +0,0 @@
-package org.eclipse.basyx.regression.directory.file;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
-
-import java.io.UnsupportedEncodingException;
-import java.net.URLEncoder;
-
-import javax.ws.rs.ServerErrorException;
-
-import org.eclipse.basyx.regression.support.server.context.ComponentsRegressionContext;
-import org.eclipse.basyx.testsuite.regression.vab.protocol.http.AASHTTPServerResource;
-import org.eclipse.basyx.tools.webserviceclient.WebServiceJSONClient;
-import org.junit.ClassRule;
-import org.junit.Test;
-
-
-
-/**
- * Test queries to CFG file provider
- * 
- * @author kuhn
- *
- */
-public class TestStaticDirectoryFileProviderExceptions {
-
-	/** 
-	 * Makes sure Tomcat Server is started
-	 */
-	@ClassRule
-	public static AASHTTPServerResource res = new AASHTTPServerResource(new ComponentsRegressionContext());
-	
-	/**
-	 * Execute test case that tests not implemented calls
-	 * 
-	 * @throws UnsupportedEncodingException
-	 */
-	@Test
-	public void testUnsupportedCalls() throws UnsupportedEncodingException {
-		// Invoke BaSyx service calls via web services
-		WebServiceJSONClient client = new WebServiceJSONClient();
-		
-		// Directory web service URL
-		String wsURL = "http://localhost:8080/basys.components/Testsuite/Directory/CFGFile";
-		
-
-		
-		// Register a new AAS (using POST)
-		try {
-			// Get a known AAS by its ID
-			client.post(wsURL + "/api/v1/registry", "Some content");
-
-			// Exception was not thrown
-			fail("Expected exception indicating that feature is not implemented was not thrown");
-		} catch (ServerErrorException e) {
-			// Check return code for expected return value (501)
-			assertEquals(501, e.getResponse().getStatus());
-			
-		}
-
-		
-		
-		// Renew a specific AAS registration (using PUT)
-		try {
-			// Get a known AAS by its ID
-			client.put(wsURL + "/api/v1/registry/urn:de.FHG:es.iese:aas:0.98:5:lab/" + URLEncoder.encode("microscope#A-19", "UTF-8"), "Some updated content");
-
-			// Exception was not thrown
-			fail("Expected exception indicating that feature is not implemented was not thrown");
-		} catch (ServerErrorException e) {
-			// Check return code for expected return value (501)
-			assertEquals(501, e.getResponse().getStatus());
-		}
-
-		
-		// Delete a specific AAS registration (using PUT)
-		try {
-			// Get a known AAS by its ID
-			client.delete(wsURL+"/api/v1/registry/urn:de.FHG:es.iese:aas:0.98:5:lab/"+URLEncoder.encode("microscope#A-19","UTF-8"));
-
-			// Exception was not thrown
-			fail("Expected exception indicating that feature is not implemented was not thrown");
-		} catch (ServerErrorException e) {
-			// Check return code for expected return value (501)
-			assertEquals(501, e.getResponse().getStatus());
-		}
-
-	}
-}
-
-
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/models/controlcomponent/TestSimpleControlComponent.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/models/controlcomponent/TestSimpleControlComponent.java
index 0841263..230cf02 100644
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/models/controlcomponent/TestSimpleControlComponent.java
+++ b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/models/controlcomponent/TestSimpleControlComponent.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.regression.models.controlcomponent;
 
 import static org.junit.Assert.assertTrue;
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/processengineconnector/DynamicActivitiProcessTest.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/processengineconnector/DynamicActivitiProcessTest.java
index 5f5f0b9..eb26743 100644
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/processengineconnector/DynamicActivitiProcessTest.java
+++ b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/processengineconnector/DynamicActivitiProcessTest.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.regression.processengineconnector;
 
 
@@ -180,4 +189,4 @@
 		output.close();
 	}
  
-}
\ No newline at end of file
+}
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/processengineconnector/TestAASServicecall.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/processengineconnector/TestAASServicecall.java
index 56a028c..2a3fdc6 100644
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/processengineconnector/TestAASServicecall.java
+++ b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/processengineconnector/TestAASServicecall.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.regression.processengineconnector;
 
 import static org.junit.Assert.assertEquals;
@@ -10,19 +19,19 @@
 import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
 import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
 import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
-import org.eclipse.basyx.aas.registration.api.IAASRegistryService;
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
 import org.eclipse.basyx.aas.registration.memory.InMemoryRegistry;
 import org.eclipse.basyx.aas.restapi.AASModelProvider;
-import org.eclipse.basyx.aas.restapi.VABMultiSubmodelProvider;
+import org.eclipse.basyx.aas.restapi.MultiSubmodelProvider;
 import org.eclipse.basyx.components.processengine.connector.DeviceServiceExecutor;
 import org.eclipse.basyx.regression.support.processengine.aas.DeviceAdministrationShellFactory;
 import org.eclipse.basyx.regression.support.processengine.stubs.CoilcarStub;
 import org.eclipse.basyx.regression.support.processengine.submodel.DeviceSubmodelFactory;
 import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
 import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
 import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
-import org.eclipse.basyx.submodel.restapi.SubModelProvider;
+import org.eclipse.basyx.submodel.restapi.SubmodelProvider;
 import org.eclipse.basyx.testsuite.regression.vab.gateway.ConnectorProviderStub;
 import org.junit.Before;
 import org.junit.Test;
@@ -76,19 +85,19 @@
 		coilcar = new CoilcarStub();
 		
 		// Create the submodel of services provided by the coilcar with id "submodel1"
-		SubModel sm = new DeviceSubmodelFactory().create(SUBMODEL_ID, coilcar);
+		Submodel sm = new DeviceSubmodelFactory().create(SUBMODEL_ID, coilcar);
 		
 		// Create VAB multi-submodel provider for holding the sub-models
-		VABMultiSubmodelProvider provider = new VABMultiSubmodelProvider();
+		MultiSubmodelProvider provider = new MultiSubmodelProvider();
 		
 		// Add sub-model to the provider
-		provider.addSubmodel(SUBMODEL_ID, new SubModelProvider(sm));
+		provider.addSubmodel(new SubmodelProvider(sm));
 		
 		// Add aas to the provider
 		provider.setAssetAdministrationShell(new AASModelProvider(aas));
 		
 		// Create registry for aas
-		IAASRegistryService registry = new InMemoryRegistry();
+		IAASRegistry registry = new InMemoryRegistry();
 		
 		// Create aas descriptor
 		IIdentifier id = new Identifier(IdentifierType.CUSTOM, AAS_ID);
@@ -96,7 +105,7 @@
 		
 		// create submodel descriptor
 		IIdentifier smId = new Identifier(IdentifierType.CUSTOM, SUBMODEL_ID);
-		SubmodelDescriptor smDescriptor = new SubmodelDescriptor("submodel1Name", smId, "/aas/submodels/"+SUBMODEL_ID);
+		SubmodelDescriptor smDescriptor = new SubmodelDescriptor("submodel1Name", smId, "/aas/submodels/" + SUBMODEL_ID + "/submodel");
 		
 		// Add submodel descriptor to aas descriptor
 		aasDescriptor.addSubmodelDescriptor(smDescriptor);
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/processengineconnector/TestJavaDelegate.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/processengineconnector/TestJavaDelegate.java
index 9eeeecf..14fcefe 100644
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/processengineconnector/TestJavaDelegate.java
+++ b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/processengineconnector/TestJavaDelegate.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.regression.processengineconnector;
 
 
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/processengineconnector/TestTransportProcess_ConfigureEngineProgrammatically.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/processengineconnector/TestTransportProcess_ConfigureEngineProgrammatically.java
index 4e616a9..0905775 100644
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/processengineconnector/TestTransportProcess_ConfigureEngineProgrammatically.java
+++ b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/processengineconnector/TestTransportProcess_ConfigureEngineProgrammatically.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.regression.processengineconnector;
 
 import java.io.File;
@@ -22,7 +31,7 @@
 import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
 import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
 import org.eclipse.basyx.testsuite.regression.vab.protocol.http.AASHTTPServerResource;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorFactory;
 import org.junit.Before;
 import org.junit.ClassRule;
 import org.junit.Test;
@@ -92,7 +101,7 @@
 		
 		// register the aas
 		registry.register(ccDescriptor);
-		manager = new ConnectedAssetAdministrationShellManager(registry, new HTTPConnectorProvider());
+		manager = new ConnectedAssetAdministrationShellManager(registry, new HTTPConnectorFactory());
 		
 		
 	}
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/rawcfgprovider/TestRawCFGProviderAAS.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/rawcfgprovider/TestRawCFGProviderAAS.java
deleted file mode 100644
index 1ef899b..0000000
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/rawcfgprovider/TestRawCFGProviderAAS.java
+++ /dev/null
@@ -1,71 +0,0 @@
-package org.eclipse.basyx.regression.rawcfgprovider;
-
-import static org.junit.Assert.assertEquals;
-
-import java.util.Map;
-
-import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
-import org.eclipse.basyx.regression.support.directory.ComponentsTestsuiteDirectory;
-import org.eclipse.basyx.regression.support.server.context.ComponentsRegressionContext;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
-import org.eclipse.basyx.testsuite.regression.vab.protocol.http.AASHTTPServerResource;
-import org.eclipse.basyx.vab.manager.VABConnectionManager;
-import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
-import org.junit.ClassRule;
-import org.junit.Test;
-
-
-
-/**
- * Test queries to CFG file provider
- * 
- * @author kuhn
- *
- */
-public class TestRawCFGProviderAAS {
-
-	
-	/**
-	 * VAB connection manager backend
-	 */
-	protected VABConnectionManager connManager = new VABConnectionManager(new ComponentsTestsuiteDirectory(), new HTTPConnectorProvider());
-
-	/** 
-	 * Makes sure Tomcat Server is started
-	 */
-	@ClassRule
-	public static AASHTTPServerResource res = new AASHTTPServerResource(new ComponentsRegressionContext());
-	
-	/**
-	 * Test basic queries
-	 */
-	@SuppressWarnings({ "unchecked" })
-	@Test
-	public void test() throws Exception {
-
-		// Connect to sub model "CfgFileTestAAS"
-		VABElementProxy connSubModel = this.connManager.connectToVABElement("AASProvider");
-
-		
-		// Create map with complex type
-		AssetAdministrationShell aas = new AssetAdministrationShell();
-		aas.setIdShort("testAAS");
-		
-		// Create AAS structure on server
-		connSubModel.createValue("/aas", aas);
-
-		
-		// Read complex property completely
-		Map<String, Object> aasReadBack = (Map<String, Object>) connSubModel.getModelPropertyValue("/aas");
-
-		assertEquals(aas.getIdShort(), AssetAdministrationShell.createAsFacade(aasReadBack).getIdShort());
-		
-		// Read AAS SubModel
-		Map<String, Object> smReadBack = (Map<String, Object>) connSubModel
-				.getModelPropertyValue("/aas/submodels/rawSampleCFG");
-		
-		assertEquals("rawSampleCFG", SubModel.createAsFacade(smReadBack).getIdShort());
-		
-	}
-}
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/rawcfgprovider/TestRawCFGProviderAASNewModel.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/rawcfgprovider/TestRawCFGProviderAASNewModel.java
deleted file mode 100644
index 8f9efc0..0000000
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/rawcfgprovider/TestRawCFGProviderAASNewModel.java
+++ /dev/null
@@ -1,62 +0,0 @@
-package org.eclipse.basyx.regression.rawcfgprovider;
-
-import static org.junit.Assert.assertEquals;
-
-import java.util.Map;
-
-import org.eclipse.basyx.regression.support.directory.ComponentsTestsuiteDirectory;
-import org.eclipse.basyx.regression.support.server.context.ComponentsRegressionContext;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
-import org.eclipse.basyx.testsuite.regression.vab.protocol.http.AASHTTPServerResource;
-import org.eclipse.basyx.vab.manager.VABConnectionManager;
-import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
-import org.junit.ClassRule;
-import org.junit.Test;
-
-
-
-/**
- * Test queries to CFG file provider
- * 
- * @author kuhn
- *
- */
-public class TestRawCFGProviderAASNewModel {
-
-	
-	/**
-	 * VAB connection manager backend
-	 */
-	protected VABConnectionManager connManager = new VABConnectionManager(new ComponentsTestsuiteDirectory(), new HTTPConnectorProvider());
-
-	/** 
-	 * Makes sure Tomcat Server is started
-	 */
-	@ClassRule
-	public static AASHTTPServerResource res = new AASHTTPServerResource(new ComponentsRegressionContext());
-	
-	/**
-	 * Test basic queries
-	 */
-	@SuppressWarnings({ "unchecked", "unused" })
-	@Test
-	public void test() throws Exception {
-
-		// Connect to sub model "CfgFileTestAAS"
-		VABElementProxy connSubModel = this.connManager.connectToVABElement("RawCfgFileTestAAS");
-
-		
-		// Create map with complex type
-		Property prop = new Property ();
-		prop.setIdShort("prop");
-		// Create AAS structure on server
-		connSubModel.createValue("/aas/submodels/rawSampleCFG/" + SubmodelElementProvider.PROPERTIES, prop);
-
-		
-		// Read complex property completely
-		Map<String, Object> aasReadBack = (Map<String, Object>) connSubModel.getModelPropertyValue("/aas/submodels/rawSampleCFG/" + SubmodelElementProvider.PROPERTIES + "/prop");
-		assertEquals(prop.getIdShort(), Property.createAsFacade(prop).getIdShort());
-	}
-}
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/rawcfgprovider/TestRawCFGProviderSimpleValues.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/rawcfgprovider/TestRawCFGProviderSimpleValues.java
deleted file mode 100644
index ef95857..0000000
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/rawcfgprovider/TestRawCFGProviderSimpleValues.java
+++ /dev/null
@@ -1,88 +0,0 @@
-package org.eclipse.basyx.regression.rawcfgprovider;
-
-import static org.junit.Assert.assertEquals;
-
-import java.util.Map;
-
-import org.eclipse.basyx.regression.support.directory.ComponentsTestsuiteDirectory;
-import org.eclipse.basyx.regression.support.server.context.ComponentsRegressionContext;
-import org.eclipse.basyx.submodel.metamodel.map.qualifier.AdministrativeInformation;
-import org.eclipse.basyx.submodel.metamodel.map.qualifier.Identifiable;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
-import org.eclipse.basyx.testsuite.regression.vab.protocol.http.AASHTTPServerResource;
-import org.eclipse.basyx.vab.manager.VABConnectionManager;
-import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
-import org.junit.ClassRule;
-import org.junit.Test;
-
-/**
- * Test queries to CFG file provider
- * 
- * @author kuhn
- *
- */
-public class TestRawCFGProviderSimpleValues {
-
-	/**
-	 * VAB connection manager backend
-	 */
-	protected VABConnectionManager connManager = new VABConnectionManager(new ComponentsTestsuiteDirectory(),
-			new HTTPConnectorProvider());
-
-	/**
-	 * Makes sure Tomcat Server is started
-	 */
-	@ClassRule
-	public static AASHTTPServerResource res = new AASHTTPServerResource(new ComponentsRegressionContext());
-
-	/**
-	 * Test basic queries
-	 */
-	@SuppressWarnings("unchecked")
-	@Test
-	public void test() throws Exception {
-
-		// Connect to sub model "CfgFileTestAAS"
-		VABElementProxy connSubModel = this.connManager.connectToVABElement("RawCfgFileTestAAS");
-
-		// Check sub model meta data
-		Map<String, Object> submodel = (Map<String, Object>) connSubModel
-				.getModelPropertyValue("/aas/submodels/rawSampleCFG");
-		assertEquals("1.0",
-				AdministrativeInformation.createAsFacade((Map<String, Object>) submodel.get(Identifiable.ADMINISTRATION))
-						.getVersion());
-
-		// Get property value
-		Map<String, Object> value1 = (Map<String, Object>) connSubModel
-				.getModelPropertyValue("/aas/submodels/rawSampleCFG/submodelElements/cfgProperty1/value");
-		assertEquals("exampleStringValueRaw", value1.get(Property.VALUE));
-		Map<String, Object> cfgProperty1 = (Map<String, Object>) connSubModel
-				.getModelPropertyValue("/aas/submodels/rawSampleCFG/" + SubmodelElementProvider.PROPERTIES + "/cfgProperty1");
-		assertEquals("Configuration property description", cfgProperty1.get("description"));
-
-		// Get property value
-		Map<String, Object> value2 = (Map<String, Object>) connSubModel
-				.getModelPropertyValue("/aas/submodels/rawSampleCFG/" + SubmodelElementProvider.PROPERTIES + "/cfgProperty2/value");
-		assertEquals(12, value2.get(Property.VALUE));
-		// - Check property meta data (description)
-		Map<String, Object> cfgProperty2 = (Map<String, Object>) connSubModel
-				.getModelPropertyValue("/aas/submodels/rawSampleCFG/" + SubmodelElementProvider.PROPERTIES + "/cfgProperty2");
-		assertEquals("Configuration property description on multiple lines", cfgProperty2.get("description"));
-
-		// Get property value
-		Map<String, Object> value3 = (Map<String, Object>) connSubModel
-				.getModelPropertyValue("/aas/submodels/rawSampleCFG/" + SubmodelElementProvider.PROPERTIES + "/cfgProperty3/value");
-		assertEquals("45.8", value3.get(Property.VALUE));
-
-		// Get property value
-		Map<String, Object> value4 = (Map<String, Object>) connSubModel
-				.getModelPropertyValue("/aas/submodels/rawSampleCFG/" + SubmodelElementProvider.PROPERTIES + "/cfgProperty4/value");
-		assertEquals("44.8", value4.get(Property.VALUE));
-		Map<String, Object> cfgProperty4 = (Map<String, Object>) connSubModel
-				.getModelPropertyValue("/aas/submodels/rawSampleCFG/" + SubmodelElementProvider.PROPERTIES + "/cfgProperty4");
-		assertEquals("Another configuration property description", cfgProperty4.get("description"));
-		assertEquals("8", cfgProperty4.get("newMetaData"));
-	}
-}
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sql/SQLInvocationsTest.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sql/SQLInvocationsTest.java
new file mode 100644
index 0000000..4c03525
--- /dev/null
+++ b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sql/SQLInvocationsTest.java
@@ -0,0 +1,85 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.regression.sql;
+
+import java.util.Collection;
+import java.util.LinkedList;
+
+import org.eclipse.basyx.regression.support.directory.ComponentsTestsuiteDirectory;
+import org.eclipse.basyx.regression.support.server.context.ComponentsRegressionContext;
+import org.eclipse.basyx.testsuite.regression.vab.protocol.http.AASHTTPServerResource;
+import org.eclipse.basyx.vab.manager.VABConnectionManager;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorFactory;
+import org.junit.ClassRule;
+import org.junit.Ignore;
+import org.junit.Test;
+
+
+
+/**
+ * Test SQL invocations
+ * 
+ * @author kuhn
+ *
+ */
+public class SQLInvocationsTest {
+
+	
+	/**
+	 * Store HTTP asset administration shell manager backend
+	 */
+	protected VABConnectionManager connManager = new VABConnectionManager(new ComponentsTestsuiteDirectory(), new HTTPConnectorFactory());
+
+	/** 
+	 * Makes sure Tomcat Server is started
+	 */
+	@ClassRule
+	public static AASHTTPServerResource res = new AASHTTPServerResource(new ComponentsRegressionContext());
+	
+	/**
+	 * Test basic queries
+	 */
+	@SuppressWarnings("unused")
+	@Test
+	@Ignore //FIXME the SQLTestSubmodel does not contain any operations
+	public void test() throws Exception {
+
+		// Connect to sub model "CfgFileTestAAS"
+		VABElementProxy connSubmodel = this.connManager.connectToVABElement("SQLTestSubmodel");
+
+		
+		// Get property value (1)
+		Object value1 = connSubmodel.invokeOperation("/aas/submodels/SQLTestSubmodel/operations/sensorIDForName", "VS_0001");
+		
+		// Get property value (2)
+		Object value2 = connSubmodel.invokeOperation("/aas/submodels/SQLTestSubmodel/operations/sensorIDForName", "VS_0002");
+
+		
+		// Call operation that inserts a value into the database
+		// - Insert line into table
+		connSubmodel.invokeOperation("/aas/submodels/SQLTestSubmodel/operations/addSensorID", "sensorname, sensorid", "'VS_0005', '321'");
+
+		// Get property value (3)
+		Object value3 = connSubmodel.invokeOperation("/aas/submodels/SQLTestSubmodel/operations/sensorIDForName", "VS_0005");
+		
+		
+		// Delete property 'VS_0005'
+		// - Collection that contains call values
+		Collection<String> callValues4 = new LinkedList<>();
+		callValues4.add("VS_0005");
+		// - Delete sensor from table
+		connSubmodel.deleteValue("/aas/submodels/SQLTestSubmodel/properties/sensorNames", callValues4);
+
+		// Get property value (4)
+		Object value4 = connSubmodel.invokeOperation("/aas/submodels/SQLTestSubmodel/operations/sensorIDForName", "VS_0005");
+	}
+}
+
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sql/SQLQueriesTest.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sql/SQLQueriesTest.java
new file mode 100644
index 0000000..f2f9983
--- /dev/null
+++ b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sql/SQLQueriesTest.java
@@ -0,0 +1,125 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.regression.sql;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.basyx.regression.support.directory.ComponentsTestsuiteDirectory;
+import org.eclipse.basyx.regression.support.server.context.ComponentsRegressionContext;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.testsuite.regression.vab.protocol.http.AASHTTPServerResource;
+import org.eclipse.basyx.vab.manager.VABConnectionManager;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorFactory;
+import org.junit.ClassRule;
+import org.junit.Ignore;
+import org.junit.Test;
+
+
+
+/**
+ * Test SQL queries
+ * 
+ * @author kuhn
+ *
+ */
+public class SQLQueriesTest {
+
+	
+	/**
+	 * Store HTTP asset administration shell manager backend
+	 */
+	protected VABConnectionManager connManager = new VABConnectionManager(new ComponentsTestsuiteDirectory(), new HTTPConnectorFactory());
+
+	/** 
+	 * Makes sure Tomcat Server is started
+	 */
+	@ClassRule
+	public static AASHTTPServerResource res = new AASHTTPServerResource(new ComponentsRegressionContext());
+	
+	
+	/**
+	 * Test basic queries
+	 */
+	@Test
+	@Ignore
+	public void test() throws Exception {
+
+		// Connect to sub model "CfgFileTestAAS"
+		VABElementProxy connSubmodel = this.connManager.connectToVABElement("SQLTestSubmodel");
+
+		
+		// Get sub model
+		Object value0A = connSubmodel.getValue("/aas/submodels/SQLTestSubmodel");
+
+		
+		// Get properties
+		Object value0B = connSubmodel.getValue("/aas/submodels/SQLTestSubmodel/dataElements");
+
+		
+		// Get property value
+		Object value1 = connSubmodel
+				.getValue("/aas/submodels/SQLTestSubmodel/dataElements/sensorNames/value");
+
+		// Get property value with meta data
+		Object value1a = connSubmodel.getValue("/aas/submodels/SQLTestSubmodel/dataElements/sensorNames");
+
+		
+		// Create a new property
+		// - HashMap that contains new table line
+		Map<String, Object> newTableLine = new HashMap<>();
+			newTableLine.put("sensorname", "VS_0003");
+			newTableLine.put("sensorid",   "033542");
+		Property p = new Property(newTableLine);
+		p.setIdShort("sensorNames");
+		// - Insert line into table
+		connSubmodel.createValue("/aas/submodels/SQLTestSubmodel/dataElements", p);
+		
+		// Get property value again
+		Object value2 = connSubmodel
+				.getValue("/aas/submodels/SQLTestSubmodel/dataElements/sensorNames/value");
+
+		Object value2a = connSubmodel.getValue("/aas/submodels/SQLTestSubmodel/dataElements/sensorNames");
+
+		
+		// Update property value
+		// - Here this adds a new value into the table
+		// - Collection that contains call values
+		Map<String, Object> updatedTableLine = new HashMap<>();
+			updatedTableLine.put("sensorname", "VS_0004");
+			updatedTableLine.put("sensorid", "033542");
+		// - Update table line
+		connSubmodel.setValue("/aas/submodels/SQLTestSubmodel/dataElements/sensorNames/value",
+				updatedTableLine);
+
+		// Get property value again
+		Object value3 = connSubmodel
+				.getValue("/aas/submodels/SQLTestSubmodel/dataElements/sensorNames/value");
+
+		
+		// Delete property with ID 033542
+		// - Map that contains call values
+		Map<String, Object> removedTableLine = new HashMap<>();
+			removedTableLine.put("sensorid", "033542");
+		// - Delete sensor from table
+		connSubmodel.deleteValue("/aas/submodels/SQLTestSubmodel/dataElements/sensorNames/value", removedTableLine);
+		
+		// Get property value again
+		Object value4 = connSubmodel
+				.getValue("/aas/submodels/SQLTestSubmodel/dataElements/sensorNames/value");
+
+		
+		
+		// Get property meta data value
+		Object value5 = connSubmodel
+				.getValue("/aas/submodels/SQLTestSubmodel/dataElements/sensorNames/category");
+	}
+}
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlprovider/SQLInvocationsTest.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlprovider/SQLInvocationsTest.java
deleted file mode 100644
index f8beb36..0000000
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlprovider/SQLInvocationsTest.java
+++ /dev/null
@@ -1,76 +0,0 @@
-package org.eclipse.basyx.regression.sqlprovider;
-
-import java.util.Collection;
-import java.util.LinkedList;
-
-import org.eclipse.basyx.regression.support.directory.ComponentsTestsuiteDirectory;
-import org.eclipse.basyx.regression.support.server.context.ComponentsRegressionContext;
-import org.eclipse.basyx.testsuite.regression.vab.protocol.http.AASHTTPServerResource;
-import org.eclipse.basyx.vab.manager.VABConnectionManager;
-import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
-import org.junit.ClassRule;
-import org.junit.Ignore;
-import org.junit.Test;
-
-
-
-/**
- * Test SQL invocations
- * 
- * @author kuhn
- *
- */
-public class SQLInvocationsTest {
-
-	
-	/**
-	 * Store HTTP asset administration shell manager backend
-	 */
-	protected VABConnectionManager connManager = new VABConnectionManager(new ComponentsTestsuiteDirectory(), new HTTPConnectorProvider());
-
-	/** 
-	 * Makes sure Tomcat Server is started
-	 */
-	@ClassRule
-	public static AASHTTPServerResource res = new AASHTTPServerResource(new ComponentsRegressionContext());
-	
-	/**
-	 * Test basic queries
-	 */
-	@SuppressWarnings("unused")
-	@Test
-	@Ignore //FIXME the SQLTestSubmodel does not contain any operations
-	public void test() throws Exception {
-
-		// Connect to sub model "CfgFileTestAAS"
-		VABElementProxy connSubModel = this.connManager.connectToVABElement("SQLTestSubmodel");
-
-		
-		// Get property value (1)
-		Object value1 = connSubModel.invokeOperation("/aas/submodels/SQLTestSubmodel/operations/sensorIDForName", "VS_0001");
-		
-		// Get property value (2)
-		Object value2 = connSubModel.invokeOperation("/aas/submodels/SQLTestSubmodel/operations/sensorIDForName", "VS_0002");
-
-		
-		// Call operation that inserts a value into the database
-		// - Insert line into table
-		connSubModel.invokeOperation("/aas/submodels/SQLTestSubmodel/operations/addSensorID", "sensorname, sensorid", "'VS_0005', '321'");
-
-		// Get property value (3)
-		Object value3 = connSubModel.invokeOperation("/aas/submodels/SQLTestSubmodel/operations/sensorIDForName", "VS_0005");
-		
-		
-		// Delete property 'VS_0005'
-		// - Collection that contains call values
-		Collection<String> callValues4 = new LinkedList<>();
-		callValues4.add("VS_0005");
-		// - Delete sensor from table
-		connSubModel.deleteValue("/aas/submodels/SQLTestSubmodel/properties/sensorNames", callValues4);
-
-		// Get property value (4)
-		Object value4 = connSubModel.invokeOperation("/aas/submodels/SQLTestSubmodel/operations/sensorIDForName", "VS_0005");
-	}
-}
-
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlprovider/SQLQueriesTest.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlprovider/SQLQueriesTest.java
deleted file mode 100644
index a06b966..0000000
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlprovider/SQLQueriesTest.java
+++ /dev/null
@@ -1,116 +0,0 @@
-package org.eclipse.basyx.regression.sqlprovider;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.eclipse.basyx.regression.support.directory.ComponentsTestsuiteDirectory;
-import org.eclipse.basyx.regression.support.server.context.ComponentsRegressionContext;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.testsuite.regression.vab.protocol.http.AASHTTPServerResource;
-import org.eclipse.basyx.vab.manager.VABConnectionManager;
-import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
-import org.junit.ClassRule;
-import org.junit.Ignore;
-import org.junit.Test;
-
-
-
-/**
- * Test SQL queries
- * 
- * @author kuhn
- *
- */
-public class SQLQueriesTest {
-
-	
-	/**
-	 * Store HTTP asset administration shell manager backend
-	 */
-	protected VABConnectionManager connManager = new VABConnectionManager(new ComponentsTestsuiteDirectory(), new HTTPConnectorProvider());
-
-	/** 
-	 * Makes sure Tomcat Server is started
-	 */
-	@ClassRule
-	public static AASHTTPServerResource res = new AASHTTPServerResource(new ComponentsRegressionContext());
-	
-	
-	/**
-	 * Test basic queries
-	 */
-	@Test
-	@Ignore
-	public void test() throws Exception {
-
-		// Connect to sub model "CfgFileTestAAS"
-		VABElementProxy connSubModel = this.connManager.connectToVABElement("SQLTestSubmodel");
-
-		
-		// Get sub model
-		Object value0A = connSubModel.getModelPropertyValue("/aas/submodels/SQLTestSubmodel");
-
-		
-		// Get properties
-		Object value0B = connSubModel.getModelPropertyValue("/aas/submodels/SQLTestSubmodel/dataElements");
-
-		
-		// Get property value
-		Object value1 = connSubModel
-				.getModelPropertyValue("/aas/submodels/SQLTestSubmodel/dataElements/sensorNames/value");
-
-		// Get property value with meta data
-		Object value1a = connSubModel.getModelPropertyValue("/aas/submodels/SQLTestSubmodel/dataElements/sensorNames");
-
-		
-		// Create a new property
-		// - HashMap that contains new table line
-		Map<String, Object> newTableLine = new HashMap<>();
-			newTableLine.put("sensorname", "VS_0003");
-			newTableLine.put("sensorid",   "033542");
-		Property p = new Property(newTableLine);
-		p.setIdShort("sensorNames");
-		// - Insert line into table
-		connSubModel.createValue("/aas/submodels/SQLTestSubmodel/dataElements", p);
-		
-		// Get property value again
-		Object value2 = connSubModel
-				.getModelPropertyValue("/aas/submodels/SQLTestSubmodel/dataElements/sensorNames/value");
-
-		Object value2a = connSubModel.getModelPropertyValue("/aas/submodels/SQLTestSubmodel/dataElements/sensorNames");
-
-		
-		// Update property value
-		// - Here this adds a new value into the table
-		// - Collection that contains call values
-		Map<String, Object> updatedTableLine = new HashMap<>();
-			updatedTableLine.put("sensorname", "VS_0004");
-			updatedTableLine.put("sensorid", "033542");
-		// - Update table line
-		connSubModel.setModelPropertyValue("/aas/submodels/SQLTestSubmodel/dataElements/sensorNames/value",
-				updatedTableLine);
-
-		// Get property value again
-		Object value3 = connSubModel
-				.getModelPropertyValue("/aas/submodels/SQLTestSubmodel/dataElements/sensorNames/value");
-
-		
-		// Delete property with ID 033542
-		// - Map that contains call values
-		Map<String, Object> removedTableLine = new HashMap<>();
-			removedTableLine.put("sensorid", "033542");
-		// - Delete sensor from table
-		connSubModel.deleteValue("/aas/submodels/SQLTestSubmodel/dataElements/sensorNames/value", removedTableLine);
-		
-		// Get property value again
-		Object value4 = connSubModel
-				.getModelPropertyValue("/aas/submodels/SQLTestSubmodel/dataElements/sensorNames/value");
-
-		
-		
-		// Get property meta data value
-		Object value5 = connSubModel
-				.getModelPropertyValue("/aas/submodels/SQLTestSubmodel/dataElements/sensorNames/category");
-	}
-}
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLConfig.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLConfig.java
index a1a592f..a483a90 100644
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLConfig.java
+++ b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLConfig.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.regression.sqlproxy;
 
 /**
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLProxyTestCollectionSetOperations.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLProxyTestCollectionSetOperations.java
index 0e18044..e54d7fa 100644
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLProxyTestCollectionSetOperations.java
+++ b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLProxyTestCollectionSetOperations.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.regression.sqlproxy;
 
 import static org.junit.Assert.assertTrue;
@@ -40,7 +49,7 @@
 		sqlRootElement.drop();
 
 		// Create new table in database for root element
-		sqlRootElement.create();
+		sqlRootElement.createRootTableIfNotExists();
 
 		// Create collection
 		Collection<Object> sqlColl = sqlRootElement.createCollection(1);
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLProxyTestCollectionSimple.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLProxyTestCollectionSimple.java
index 0b4f6c6..e13d8fe 100644
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLProxyTestCollectionSimple.java
+++ b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLProxyTestCollectionSimple.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.regression.sqlproxy;
 
 import static org.junit.Assert.assertTrue;
@@ -41,7 +50,7 @@
 		sqlRootElement.drop();
 
 		// Create new table in database for root element
-		sqlRootElement.create();
+		sqlRootElement.createRootTableIfNotExists();
 
 		// Create collection
 		Collection<Object> sqlColl = sqlRootElement.createCollection(1);
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLProxyTestCollectionTypes.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLProxyTestCollectionTypes.java
index 606cf87..ed03ba1 100644
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLProxyTestCollectionTypes.java
+++ b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLProxyTestCollectionTypes.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.regression.sqlproxy;
 
 import static org.junit.Assert.assertTrue;
@@ -41,7 +50,7 @@
 		sqlRootElement.drop();
 
 		// Create new table in database for root element
-		sqlRootElement.create();
+		sqlRootElement.createRootTableIfNotExists();
 
 		// Create collection
 		Collection<Object> sqlColl = sqlRootElement.createCollection(1);
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLProxyTestMapArrayTypes.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLProxyTestMapArrayTypes.java
index 024dde1..d84053c 100644
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLProxyTestMapArrayTypes.java
+++ b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLProxyTestMapArrayTypes.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.regression.sqlproxy;
 
 import static org.junit.Assert.assertTrue;
@@ -40,7 +49,7 @@
 		sqlRootElement.drop();
 
 		// Create new table in database for root element
-		sqlRootElement.create();
+		sqlRootElement.createRootTableIfNotExists();
 
 		// Create new SQL map
 		Map<String, Object> sqlMap = sqlRootElement.createMap(1);
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLProxyTestMapSetOperations.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLProxyTestMapSetOperations.java
index 12a4c6c..fec4a59 100644
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLProxyTestMapSetOperations.java
+++ b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLProxyTestMapSetOperations.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.regression.sqlproxy;
 
 import static org.junit.Assert.assertTrue;
@@ -46,7 +55,7 @@
 		sqlRootElement.drop();
 
 		// Create new table in database for root element
-		sqlRootElement.create();
+		sqlRootElement.createRootTableIfNotExists();
 
 		// Create new SQL map
 		Map<String, Object> sqlMap = sqlRootElement.createMap(1);
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLProxyTestMapSimple.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLProxyTestMapSimple.java
index b198ccf..62e7a5b 100644
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLProxyTestMapSimple.java
+++ b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLProxyTestMapSimple.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.regression.sqlproxy;
 
 import static org.junit.Assert.assertTrue;
@@ -41,7 +50,7 @@
 		sqlRootElement.drop();
 
 		// Create new table in database for root element
-		sqlRootElement.create();
+		sqlRootElement.createRootTableIfNotExists();
 
 		// Create new SQL map
 		Map<String, Object> sqlMap = sqlRootElement.createMap(1);
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLProxyTestMapSimpleTypes.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLProxyTestMapSimpleTypes.java
index ff26f0a..2df7ea5 100644
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLProxyTestMapSimpleTypes.java
+++ b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLProxyTestMapSimpleTypes.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.regression.sqlproxy;
 
 import static org.junit.Assert.assertTrue;
@@ -39,7 +48,7 @@
 		sqlRootElement.drop();
 
 		// Create new table in database for root element
-		sqlRootElement.create();
+		sqlRootElement.createRootTableIfNotExists();
 
 		// Create new SQL map
 		Map<String, Object> sqlMap = sqlRootElement.createMap(1);
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLProxyTestRootElement.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLProxyTestRootElement.java
index fdb94ea..8ffeac1 100644
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLProxyTestRootElement.java
+++ b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLProxyTestRootElement.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.regression.sqlproxy;
 
 import static org.junit.Assert.assertTrue;
@@ -32,7 +41,7 @@
 		// Create SQL root element
 		sqlRootElement = new SQLRootElement(SQLConfig.SQLUSER, SQLConfig.SQLPW,  "//localhost/basyx-map?", "org.postgresql.Driver", "jdbc:postgresql:", "root_el_01");
 		// - Create new table in database for root element
-		sqlRootElement.create();
+		sqlRootElement.createRootTableIfNotExists();
 		
 		// Get element IDs
 		assertTrue(sqlRootElement.getNextIdentifier() == 1);
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLProxyTestRootElementSQLElements.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLProxyTestRootElementSQLElements.java
index 4839945..90aff02 100644
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLProxyTestRootElementSQLElements.java
+++ b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlproxy/SQLProxyTestRootElementSQLElements.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.regression.sqlproxy;
 
 import static org.junit.Assert.assertTrue;
@@ -37,7 +46,7 @@
 		sqlRootElement = new SQLRootElement(SQLConfig.SQLUSER, SQLConfig.SQLPW,  "//localhost/basyx-map?", "org.postgresql.Driver", "jdbc:postgresql:", "root_el_01");
 		// - Create new table in database for root element
 		sqlRootElement.drop();
-		sqlRootElement.create();
+		sqlRootElement.createRootTableIfNotExists();
 		
 		// Create map
 		Map<String, Object> rootMap = sqlRootElement.createMap(0);
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/bundle/TestAASBundleDescriptorFactory.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/bundle/TestAASBundleDescriptorFactory.java
index 42d5003..95e63c2 100644
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/bundle/TestAASBundleDescriptorFactory.java
+++ b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/bundle/TestAASBundleDescriptorFactory.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.regression.support.bundle;
 
 import static org.junit.Assert.assertEquals;
@@ -7,7 +16,8 @@
 import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
 import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
 import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
 import org.eclipse.basyx.support.bundle.AASBundle;
 import org.eclipse.basyx.support.bundle.AASBundleDescriptorFactory;
 import org.eclipse.basyx.vab.modelprovider.VABPathTools;
@@ -24,10 +34,10 @@
 	public void testDescriptorCreation() {
 		String aasId = "aasId";
 		AssetAdministrationShell shell = new AssetAdministrationShell();
-		shell.setIdShort(aasId);
+		shell.setIdentification(new Identifier(IdentifierType.CUSTOM, aasId));
 
 		String smId = "smId";
-		SubModel sm = new SubModel();
+		Submodel sm = new Submodel();
 		sm.setIdShort(smId);
 		sm.setIdentification(IdentifierType.IRI, "aasIdIRI");
 
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/bundle/TestAASBundleHelper.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/bundle/TestAASBundleHelper.java
new file mode 100644
index 0000000..8c28852
--- /dev/null
+++ b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/bundle/TestAASBundleHelper.java
@@ -0,0 +1,173 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.regression.support.bundle;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.basyx.aas.aggregator.AASAggregator;
+import org.eclipse.basyx.aas.aggregator.proxy.AASAggregatorProxy;
+import org.eclipse.basyx.aas.aggregator.restapi.AASAggregatorProvider;
+import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
+import org.eclipse.basyx.aas.registration.memory.InMemoryRegistry;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.facade.SubmodelElementMapCollectionConverter;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.eclipse.basyx.support.bundle.AASBundle;
+import org.eclipse.basyx.support.bundle.AASBundleHelper;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Test for the AASBundelIntegrator
+ * 
+ * @author conradi
+ *
+ */
+public class TestAASBundleHelper {
+
+	private static final String AAS_ID = "TestAAS";
+	private static final String SM_ID = "TestSM";
+	
+	
+	private AASAggregatorProxy aggregator;
+	private List<AASBundle> bundles;
+	private AASAggregatorProvider provider;
+	
+	
+	
+	@Before
+	public void init() {
+		provider = new AASAggregatorProvider(new AASAggregator());
+		aggregator = new AASAggregatorProxy(new VABElementProxy("/shells", provider));
+		bundles = new ArrayList<>();		
+	}
+	
+	/**
+	 * This test loads an AAS and its two Submodels into the Aggregator,
+	 * runs the integration with AAS and Submodels with the same IDs, but different content,
+	 * checks if integration does NOT replace the models in the Aggregator. 
+	 */
+	@Test
+	public void testIntegrationOfExistingAASAndSM() {
+		AASBundle bundle = getTestBundle();
+		bundles.add(bundle);
+		
+		// Load AAS and SM AASAggregator
+		AssetAdministrationShell aas = (AssetAdministrationShell) bundle.getAAS();
+		Set<ISubmodel> submodels = bundle.getSubmodels();
+		Submodel sm = (Submodel) submodels.iterator().next();
+		pushAAS(aas);
+		pushSubmodel(sm, aas.getIdentification());
+		
+		assertFalse(AASBundleHelper.integrate(aggregator, bundles));
+		checkAggregatorContent();
+	}
+	
+	/**
+	 * This test loads an AAS into the Aggregator,
+	 * runs the integration with the AAS and a SM,
+	 * checks if both is present in Aggregator afterwards. 
+	 */
+	@Test
+	public void testIntegrationOfExistingAASAndNonexistingSM() {
+		AASBundle bundle = getTestBundle();
+		bundles.add(bundle);
+		
+		// Load only AAS into AASAggregator
+		AssetAdministrationShell aas = (AssetAdministrationShell) bundle.getAAS();
+		pushAAS(aas);
+		
+		assertTrue(AASBundleHelper.integrate(aggregator, bundles));
+		checkAggregatorContent();
+	}
+	
+	/**
+	 * This test loads nothing into the Aggregator,
+	 * runs the integration with the AAS and a SM,
+	 * checks if both is present in Aggregator afterwards. 
+	 */
+	@Test
+	public void testIntegrationOfNonexistingAASAndSM() {
+		AASBundle bundle = getTestBundle();
+		bundles.add(bundle);
+		
+		assertTrue(AASBundleHelper.integrate(aggregator, bundles));
+		checkAggregatorContent();
+	}
+	
+	/**
+	 * This test loads nothing into the Aggregator,
+	 * runs the integration with the AAS and a SM,
+	 * checks if both is present in Aggregator afterwards. Furthermore,
+	 * the AASAggregator has a registry for registering and resolving potential
+	 * submodels.
+	 */
+	@Test
+	public void testIntegrationOfNonexistingAASAndSMWithRegistry() {
+		IAASRegistry registry = new InMemoryRegistry();
+		provider = new AASAggregatorProvider(new AASAggregator(registry));
+		aggregator = new AASAggregatorProxy(new VABElementProxy("/shells", provider));
+
+		AASBundle bundle = getTestBundle();
+		bundles.add(bundle);
+
+		assertTrue(AASBundleHelper.integrate(aggregator, bundles));
+		checkAggregatorContent();
+	}
+
+	@SuppressWarnings("unchecked")
+	private void checkAggregatorContent() {
+		IAssetAdministrationShell aas = aggregator.getAAS(new Identifier(IdentifierType.CUSTOM, AAS_ID));
+		assertEquals(AAS_ID, aas.getIdShort());
+		IModelProvider provider = aggregator.getAASProvider(new Identifier(IdentifierType.CUSTOM, AAS_ID));
+		
+		Submodel sm = SubmodelElementMapCollectionConverter.mapToSM(
+				(Map<String, Object>) provider.getValue("/aas/submodels/" + SM_ID));
+		
+		assertEquals(SM_ID, sm.getIdentification().getId());
+	}
+	
+	private void pushAAS(AssetAdministrationShell aas) {
+		aggregator.createAAS(aas);
+	}
+	
+	private void pushSubmodel(Submodel sm, IIdentifier aasIdentifier) {
+		provider.setValue("/" + AASAggregatorProvider.PREFIX + "/" + aasIdentifier.getId() + "/aas/submodels/" + sm.getIdShort(), sm);
+	}
+	
+	private AASBundle getTestBundle() {
+		Submodel sm = new Submodel();
+		sm.setIdShort(SM_ID);
+		sm.setIdentification(IdentifierType.CUSTOM, SM_ID);
+
+		AssetAdministrationShell aas = new AssetAdministrationShell();
+		aas.setIdentification(IdentifierType.CUSTOM, AAS_ID);
+		aas.setIdShort(AAS_ID);
+		aas.addSubmodel(sm);
+
+		return new AASBundle(aas, new HashSet<>(Arrays.asList(sm)));
+	}
+}
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/directory/ComponentsTestsuiteDirectory.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/directory/ComponentsTestsuiteDirectory.java
index 523136d..32f3923 100644
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/directory/ComponentsTestsuiteDirectory.java
+++ b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/directory/ComponentsTestsuiteDirectory.java
@@ -1,6 +1,15 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.regression.support.directory;
 
-import org.eclipse.basyx.vab.directory.memory.InMemoryDirectory;
+import org.eclipse.basyx.vab.registry.memory.VABInMemoryRegistry;
 
 
 
@@ -11,7 +20,7 @@
  * @author kuhn
  *
  */
-public class ComponentsTestsuiteDirectory extends InMemoryDirectory {
+public class ComponentsTestsuiteDirectory extends VABInMemoryRegistry {
 
 	
 	/**
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/aas/DeviceAdministrationShellFactory.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/aas/DeviceAdministrationShellFactory.java
index 4d5831d..ae86a08 100644
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/aas/DeviceAdministrationShellFactory.java
+++ b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/aas/DeviceAdministrationShellFactory.java
@@ -1,9 +1,20 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.regression.support.processengine.aas;
 
+import org.eclipse.basyx.aas.metamodel.api.parts.asset.AssetKind;
 import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.map.parts.Asset;
 import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
 import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
 import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
 
 public class DeviceAdministrationShellFactory {
@@ -11,11 +22,11 @@
 	public AssetAdministrationShell create(String aasid, String submodelid) {
 		// create the aas, add submodel to aas using VABMultiSubmodelProvider
 		IIdentifier id = new Identifier(IdentifierType.CUSTOM, submodelid);
-		SubModel sm = new SubModel();
+		Submodel sm = new Submodel();
 		sm.setIdentification(id.getIdType(), id.getId());
-		AssetAdministrationShell aas = new AssetAdministrationShell();
-		aas.addSubModel(sm);
-		aas.put("idshort", aasid);
+		sm.setIdShort("smIdShort");
+		AssetAdministrationShell aas = new AssetAdministrationShell(aasid, new Identifier(IdentifierType.CUSTOM, aasid + "Id"), new Asset("assetId", new Identifier(IdentifierType.CUSTOM, aasid + "assetId"), AssetKind.INSTANCE));
+		aas.addSubmodel(sm);
 
 		return aas;
 	}
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/servlet/CoilcarAASServlet.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/servlet/CoilcarAASServlet.java
index 427ffff..dfc1709 100644
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/servlet/CoilcarAASServlet.java
+++ b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/servlet/CoilcarAASServlet.java
@@ -1,13 +1,22 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.regression.support.processengine.servlet;
 
 import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
 import org.eclipse.basyx.aas.restapi.AASModelProvider;
-import org.eclipse.basyx.aas.restapi.VABMultiSubmodelProvider;
+import org.eclipse.basyx.aas.restapi.MultiSubmodelProvider;
 import org.eclipse.basyx.regression.support.processengine.aas.DeviceAdministrationShellFactory;
 import org.eclipse.basyx.regression.support.processengine.stubs.Coilcar;
 import org.eclipse.basyx.regression.support.processengine.submodel.DeviceSubmodelFactory;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
-import org.eclipse.basyx.submodel.restapi.SubModelProvider;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.restapi.SubmodelProvider;
 import org.eclipse.basyx.vab.protocol.http.server.VABHTTPInterface;
 
 /**
@@ -16,13 +25,13 @@
  * @author zhangzai
  *
  */
-public class CoilcarAASServlet extends VABHTTPInterface<VABMultiSubmodelProvider> {
+public class CoilcarAASServlet extends VABHTTPInterface<MultiSubmodelProvider> {
 	private static final long serialVersionUID = 1L;
 	private String aasid = "coilcar";
 	private String submodelid = "submodel1";
 
 	public CoilcarAASServlet() {
-		super(new VABMultiSubmodelProvider());
+		super(new MultiSubmodelProvider());
 
 		// Create the aas
 		AssetAdministrationShell coilcarAAS = new DeviceAdministrationShellFactory().create(aasid, submodelid);
@@ -31,10 +40,10 @@
 		coilcarAAS.setIdShort(aasid);
 
 		// Create the sub-model
-		SubModel coilcarSubmodel = new DeviceSubmodelFactory().create(submodelid, new Coilcar());
+		Submodel coilcarSubmodel = new DeviceSubmodelFactory().create(submodelid, new Coilcar());
 
 		getModelProvider().setAssetAdministrationShell(new AASModelProvider(coilcarAAS));
-		getModelProvider().addSubmodel(submodelid, new SubModelProvider(coilcarSubmodel));
+		getModelProvider().addSubmodel(new SubmodelProvider(coilcarSubmodel));
 	}
 
-}
\ No newline at end of file
+}
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/stubs/BPMNEngineStub.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/stubs/BPMNEngineStub.java
index ebd37b7..0b2302d 100644
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/stubs/BPMNEngineStub.java
+++ b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/stubs/BPMNEngineStub.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.regression.support.processengine.stubs;
 
 import java.lang.reflect.Field;
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/stubs/BPMNModelFactory.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/stubs/BPMNModelFactory.java
index 35e515e..d63b000 100644
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/stubs/BPMNModelFactory.java
+++ b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/stubs/BPMNModelFactory.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.regression.support.processengine.stubs;
 
 import static org.camunda.bpm.model.bpmn.impl.BpmnModelConstants.CAMUNDA_NS;
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/stubs/Coilcar.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/stubs/Coilcar.java
index c9db39d..77deec6 100644
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/stubs/Coilcar.java
+++ b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/stubs/Coilcar.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.regression.support.processengine.stubs;
 
 import org.slf4j.Logger;
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/stubs/CoilcarStub.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/stubs/CoilcarStub.java
index 10ee907..b00d284 100644
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/stubs/CoilcarStub.java
+++ b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/stubs/CoilcarStub.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.regression.support.processengine.stubs;
 
 
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/stubs/DeviceServiceExecutorStub.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/stubs/DeviceServiceExecutorStub.java
index bce54c5..3edb2af 100644
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/stubs/DeviceServiceExecutorStub.java
+++ b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/stubs/DeviceServiceExecutorStub.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.regression.support.processengine.stubs;
 
 import java.util.List;
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/stubs/ICoilcar.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/stubs/ICoilcar.java
index 76d0e8b..7e7b387 100644
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/stubs/ICoilcar.java
+++ b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/stubs/ICoilcar.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.regression.support.processengine.stubs;
 
 public interface ICoilcar {
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/stubs/ProcessInstanceStub.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/stubs/ProcessInstanceStub.java
index 732691e..8b25108 100644
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/stubs/ProcessInstanceStub.java
+++ b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/stubs/ProcessInstanceStub.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.regression.support.processengine.stubs;
 
 import org.camunda.bpm.engine.impl.pvm.runtime.ExecutionImpl;
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/submodel/DeviceSubmodelFactory.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/submodel/DeviceSubmodelFactory.java
index 1e1f82d..69a358a 100644
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/submodel/DeviceSubmodelFactory.java
+++ b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/submodel/DeviceSubmodelFactory.java
@@ -1,17 +1,30 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.regression.support.processengine.submodel;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 import java.util.function.Function;
 
 import org.eclipse.basyx.regression.support.processengine.stubs.ICoilcar;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.OperationVariable;
 
 
 public class DeviceSubmodelFactory {
-	public SubModel create(String id, ICoilcar coilcar) {
+	public Submodel create(String id, ICoilcar coilcar) {
 		// create a single value property
 		Property property1 = new Property(0);
 		property1.setIdShort("currentPosition");
@@ -26,12 +39,16 @@
 		Operation op1 = new Operation((Function<Object[], Object>) obj -> {
 			return coilcar.liftTo((int)obj[0]);
 		});
+		op1.setInputVariables(Collections.singletonList(new OperationVariable(new Property("position", 0))));
+		op1.setOutputVariables(Collections.singletonList(new OperationVariable(new Property("result", 0))));
 		op1.setIdShort("liftTo");
 		
 		Operation op2 = new Operation((Function<Object[], Object>) obj -> {
 			coilcar.moveTo((int)obj[0]);
 			return true;
 		});
+		op2.setInputVariables(Collections.singletonList(new OperationVariable(new Property("position", 0))));
+		op2.setOutputVariables(Collections.singletonList(new OperationVariable(new Property("result", 0))));
 		op2.setIdShort("moveTo");
 		
 		// create a list for defined operations
@@ -44,9 +61,9 @@
 		propList.add(property2);
 		propList.add(property3);
 		// create the sub-model and add the property and operations to the sub-model
-		SubModel sm = new SubModel(propList, opList);
-
-		sm.setIdShort(id);
+		Submodel sm = new Submodel(id, new Identifier(IdentifierType.CUSTOM, id + "Custom"));
+		propList.forEach(sm::addSubmodelElement);
+		opList.forEach(sm::addSubmodelElement);
 		return sm;
 	}
 }
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/server/context/ComponentsRegressionContext.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/server/context/ComponentsRegressionContext.java
index aebfe25..ab98927 100644
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/server/context/ComponentsRegressionContext.java
+++ b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/server/context/ComponentsRegressionContext.java
@@ -1,9 +1,14 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.regression.support.server.context;
 
-import org.eclipse.basyx.components.servlet.registry.StaticCFGDirectoryServlet;
-import org.eclipse.basyx.components.servlet.submodel.SQLSubModelProviderServlet;
-import org.eclipse.basyx.components.servlet.submodel.cfg.CFGSubModelProviderServlet;
-import org.eclipse.basyx.components.servlet.submodel.cfg.RawCFGSubModelProviderServlet;
 import org.eclipse.basyx.regression.support.processengine.servlet.CoilcarAASServlet;
 import org.eclipse.basyx.vab.protocol.http.server.BaSyxContext;
 
@@ -33,10 +38,6 @@
 		super("/basys.components", "");
 		
 		// Define Servlet infrastructure
-		addServletMapping("/Testsuite/components/BaSys/1.0/provider/sqlsm/*",     new SQLSubModelProviderServlet().withParameter("config", "/WebContent/WEB-INF/config/sqlprovider/sampledb.properties"));
-		addServletMapping("/Testsuite/components/BaSys/1.0/provider/cfgsm/*",     new CFGSubModelProviderServlet().withParameter("config", "/WebContent/WEB-INF/config/cfgprovider/samplecfg.properties"));
-		addServletMapping("/Testsuite/components/BaSys/1.0/provider/rawcfgsm/*",  new RawCFGSubModelProviderServlet().withParameter("config", "/WebContent/WEB-INF/config/rawcfgprovider/samplecfg.properties"));
-		addServletMapping("/Testsuite/Directory/CFGFile/*",                       new StaticCFGDirectoryServlet().withParameter("config", "/WebContent/WEB-INF/config/directory/cfgdirectory/directory.properties"));
 		addServletMapping("/Testsuite/Processengine/coilcar/*",                   new CoilcarAASServlet());
 	}
 }
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/xml/TestXMLAASBundleFactory.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/xml/TestXMLAASBundleFactory.java
index 3817d18..9e3836c 100644
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/xml/TestXMLAASBundleFactory.java
+++ b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/xml/TestXMLAASBundleFactory.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.regression.xml;
 
 import static org.junit.Assert.assertTrue;
@@ -10,7 +19,7 @@
 
 import org.eclipse.basyx.components.configuration.BaSyxConfiguration;
 import org.eclipse.basyx.components.xml.XMLAASBundleFactory;
-import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
 import org.eclipse.basyx.support.bundle.AASBundle;
 import org.junit.Test;
 import org.xml.sax.SAXException;
@@ -51,11 +60,11 @@
 		AASBundle minimalAASBundle = minimalBundleOptional.get();
 
 		// Check full AAS
-		Set<ISubModel> fullAASSM = fullAASBundle.getSubmodels();
+		Set<ISubmodel> fullAASSM = fullAASBundle.getSubmodels();
 		assertTrue(fullAASSM.stream().anyMatch(s -> s.getIdentification().getId().equals("http://www.zvei.de/demo/submodel/12345679")));
 
 		// Check minimal AAS
-		Set<ISubModel> minimalAASSM = minimalAASBundle.getSubmodels();
+		Set<ISubmodel> minimalAASSM = minimalAASBundle.getSubmodels();
 		assertTrue(minimalAASSM.isEmpty());
 	}
 }
diff --git a/components/basys.components/docker-compose.yml b/components/basys.components/docker-compose.yml
new file mode 100644
index 0000000..749de1f
--- /dev/null
+++ b/components/basys.components/docker-compose.yml
@@ -0,0 +1,17 @@
+version: '2.1'
+services:
+  postgres:
+    image: postgres:12.1
+    container_name: postgres
+    environment:
+      - POSTGRES_USER:'postgres'
+      - POSTGRES_PASSWORD:'admin'
+      - POSTGRES_DB=basyx-directory
+    ports:
+      - 127.0.0.1:5432:5432
+    healthcheck:
+      test: ["CMD-SHELL", "pg_isready -U postgres"]
+      interval: 3s
+      timeout: 3s
+      retries: 5
+
diff --git a/components/basys.components/mvnw b/components/basys.components/mvnw
new file mode 100755
index 0000000..a16b543
--- /dev/null
+++ b/components/basys.components/mvnw
@@ -0,0 +1,310 @@
+#!/bin/sh
+# ----------------------------------------------------------------------------
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#    https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+# ----------------------------------------------------------------------------
+
+# ----------------------------------------------------------------------------
+# Maven Start Up Batch script
+#
+# Required ENV vars:
+# ------------------
+#   JAVA_HOME - location of a JDK home dir
+#
+# Optional ENV vars
+# -----------------
+#   M2_HOME - location of maven2's installed home dir
+#   MAVEN_OPTS - parameters passed to the Java VM when running Maven
+#     e.g. to debug Maven itself, use
+#       set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
+#   MAVEN_SKIP_RC - flag to disable loading of mavenrc files
+# ----------------------------------------------------------------------------
+
+if [ -z "$MAVEN_SKIP_RC" ] ; then
+
+  if [ -f /etc/mavenrc ] ; then
+    . /etc/mavenrc
+  fi
+
+  if [ -f "$HOME/.mavenrc" ] ; then
+    . "$HOME/.mavenrc"
+  fi
+
+fi
+
+# OS specific support.  $var _must_ be set to either true or false.
+cygwin=false;
+darwin=false;
+mingw=false
+case "`uname`" in
+  CYGWIN*) cygwin=true ;;
+  MINGW*) mingw=true;;
+  Darwin*) darwin=true
+    # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
+    # See https://developer.apple.com/library/mac/qa/qa1170/_index.html
+    if [ -z "$JAVA_HOME" ]; then
+      if [ -x "/usr/libexec/java_home" ]; then
+        export JAVA_HOME="`/usr/libexec/java_home`"
+      else
+        export JAVA_HOME="/Library/Java/Home"
+      fi
+    fi
+    ;;
+esac
+
+if [ -z "$JAVA_HOME" ] ; then
+  if [ -r /etc/gentoo-release ] ; then
+    JAVA_HOME=`java-config --jre-home`
+  fi
+fi
+
+if [ -z "$M2_HOME" ] ; then
+  ## resolve links - $0 may be a link to maven's home
+  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
+
+  saveddir=`pwd`
+
+  M2_HOME=`dirname "$PRG"`/..
+
+  # make it fully qualified
+  M2_HOME=`cd "$M2_HOME" && pwd`
+
+  cd "$saveddir"
+  # echo Using m2 at $M2_HOME
+fi
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched
+if $cygwin ; then
+  [ -n "$M2_HOME" ] &&
+    M2_HOME=`cygpath --unix "$M2_HOME"`
+  [ -n "$JAVA_HOME" ] &&
+    JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+  [ -n "$CLASSPATH" ] &&
+    CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
+fi
+
+# For Mingw, ensure paths are in UNIX format before anything is touched
+if $mingw ; then
+  [ -n "$M2_HOME" ] &&
+    M2_HOME="`(cd "$M2_HOME"; pwd)`"
+  [ -n "$JAVA_HOME" ] &&
+    JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
+fi
+
+if [ -z "$JAVA_HOME" ]; then
+  javaExecutable="`which javac`"
+  if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
+    # readlink(1) is not available as standard on Solaris 10.
+    readLink=`which readlink`
+    if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
+      if $darwin ; then
+        javaHome="`dirname \"$javaExecutable\"`"
+        javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
+      else
+        javaExecutable="`readlink -f \"$javaExecutable\"`"
+      fi
+      javaHome="`dirname \"$javaExecutable\"`"
+      javaHome=`expr "$javaHome" : '\(.*\)/bin'`
+      JAVA_HOME="$javaHome"
+      export JAVA_HOME
+    fi
+  fi
+fi
+
+if [ -z "$JAVACMD" ] ; then
+  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
+  else
+    JAVACMD="`which java`"
+  fi
+fi
+
+if [ ! -x "$JAVACMD" ] ; then
+  echo "Error: JAVA_HOME is not defined correctly." >&2
+  echo "  We cannot execute $JAVACMD" >&2
+  exit 1
+fi
+
+if [ -z "$JAVA_HOME" ] ; then
+  echo "Warning: JAVA_HOME environment variable is not set."
+fi
+
+CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
+
+# traverses directory structure from process work directory to filesystem root
+# first directory with .mvn subdirectory is considered project base directory
+find_maven_basedir() {
+
+  if [ -z "$1" ]
+  then
+    echo "Path not specified to find_maven_basedir"
+    return 1
+  fi
+
+  basedir="$1"
+  wdir="$1"
+  while [ "$wdir" != '/' ] ; do
+    if [ -d "$wdir"/.mvn ] ; then
+      basedir=$wdir
+      break
+    fi
+    # workaround for JBEAP-8937 (on Solaris 10/Sparc)
+    if [ -d "${wdir}" ]; then
+      wdir=`cd "$wdir/.."; pwd`
+    fi
+    # end of workaround
+  done
+  echo "${basedir}"
+}
+
+# concatenates all lines of a file
+concat_lines() {
+  if [ -f "$1" ]; then
+    echo "$(tr -s '\n' ' ' < "$1")"
+  fi
+}
+
+BASE_DIR=`find_maven_basedir "$(pwd)"`
+if [ -z "$BASE_DIR" ]; then
+  exit 1;
+fi
+
+##########################################################################################
+# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
+# This allows using the maven wrapper in projects that prohibit checking in binary data.
+##########################################################################################
+if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
+    if [ "$MVNW_VERBOSE" = true ]; then
+      echo "Found .mvn/wrapper/maven-wrapper.jar"
+    fi
+else
+    if [ "$MVNW_VERBOSE" = true ]; then
+      echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
+    fi
+    if [ -n "$MVNW_REPOURL" ]; then
+      jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
+    else
+      jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
+    fi
+    while IFS="=" read key value; do
+      case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
+      esac
+    done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
+    if [ "$MVNW_VERBOSE" = true ]; then
+      echo "Downloading from: $jarUrl"
+    fi
+    wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
+    if $cygwin; then
+      wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"`
+    fi
+
+    if command -v wget > /dev/null; then
+        if [ "$MVNW_VERBOSE" = true ]; then
+          echo "Found wget ... using wget"
+        fi
+        if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
+            wget "$jarUrl" -O "$wrapperJarPath"
+        else
+            wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath"
+        fi
+    elif command -v curl > /dev/null; then
+        if [ "$MVNW_VERBOSE" = true ]; then
+          echo "Found curl ... using curl"
+        fi
+        if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
+            curl -o "$wrapperJarPath" "$jarUrl" -f
+        else
+            curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f
+        fi
+
+    else
+        if [ "$MVNW_VERBOSE" = true ]; then
+          echo "Falling back to using Java to download"
+        fi
+        javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
+        # For Cygwin, switch paths to Windows format before running javac
+        if $cygwin; then
+          javaClass=`cygpath --path --windows "$javaClass"`
+        fi
+        if [ -e "$javaClass" ]; then
+            if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
+                if [ "$MVNW_VERBOSE" = true ]; then
+                  echo " - Compiling MavenWrapperDownloader.java ..."
+                fi
+                # Compiling the Java class
+                ("$JAVA_HOME/bin/javac" "$javaClass")
+            fi
+            if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
+                # Running the downloader
+                if [ "$MVNW_VERBOSE" = true ]; then
+                  echo " - Running MavenWrapperDownloader.java ..."
+                fi
+                ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
+            fi
+        fi
+    fi
+fi
+##########################################################################################
+# End of extension
+##########################################################################################
+
+export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
+if [ "$MVNW_VERBOSE" = true ]; then
+  echo $MAVEN_PROJECTBASEDIR
+fi
+MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin; then
+  [ -n "$M2_HOME" ] &&
+    M2_HOME=`cygpath --path --windows "$M2_HOME"`
+  [ -n "$JAVA_HOME" ] &&
+    JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
+  [ -n "$CLASSPATH" ] &&
+    CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
+  [ -n "$MAVEN_PROJECTBASEDIR" ] &&
+    MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
+fi
+
+# Provide a "standardized" way to retrieve the CLI args that will
+# work with both Windows and non-Windows executions.
+MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
+export MAVEN_CMD_LINE_ARGS
+
+WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
+
+exec "$JAVACMD" \
+  $MAVEN_OPTS \
+  -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
+  "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
+  ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
diff --git a/components/basys.components/mvnw.cmd b/components/basys.components/mvnw.cmd
new file mode 100644
index 0000000..c8d4337
--- /dev/null
+++ b/components/basys.components/mvnw.cmd
@@ -0,0 +1,182 @@
+@REM ----------------------------------------------------------------------------
+@REM Licensed to the Apache Software Foundation (ASF) under one
+@REM or more contributor license agreements.  See the NOTICE file
+@REM distributed with this work for additional information
+@REM regarding copyright ownership.  The ASF licenses this file
+@REM to you under the Apache License, Version 2.0 (the
+@REM "License"); you may not use this file except in compliance
+@REM with the License.  You may obtain a copy of the License at
+@REM
+@REM    https://www.apache.org/licenses/LICENSE-2.0
+@REM
+@REM Unless required by applicable law or agreed to in writing,
+@REM software distributed under the License is distributed on an
+@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+@REM KIND, either express or implied.  See the License for the
+@REM specific language governing permissions and limitations
+@REM under the License.
+@REM ----------------------------------------------------------------------------
+
+@REM ----------------------------------------------------------------------------
+@REM Maven Start Up Batch script
+@REM
+@REM Required ENV vars:
+@REM JAVA_HOME - location of a JDK home dir
+@REM
+@REM Optional ENV vars
+@REM M2_HOME - location of maven2's installed home dir
+@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
+@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
+@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
+@REM     e.g. to debug Maven itself, use
+@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
+@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
+@REM ----------------------------------------------------------------------------
+
+@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
+@echo off
+@REM set title of command window
+title %0
+@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
+@if "%MAVEN_BATCH_ECHO%" == "on"  echo %MAVEN_BATCH_ECHO%
+
+@REM set %HOME% to equivalent of $HOME
+if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
+
+@REM Execute a user defined script before this one
+if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
+@REM check for pre script, once with legacy .bat ending and once with .cmd ending
+if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
+if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
+:skipRcPre
+
+@setlocal
+
+set ERROR_CODE=0
+
+@REM To isolate internal variables from possible post scripts, we use another setlocal
+@setlocal
+
+@REM ==== START VALIDATION ====
+if not "%JAVA_HOME%" == "" goto OkJHome
+
+echo.
+echo Error: JAVA_HOME not found in your environment. >&2
+echo Please set the JAVA_HOME variable in your environment to match the >&2
+echo location of your Java installation. >&2
+echo.
+goto error
+
+:OkJHome
+if exist "%JAVA_HOME%\bin\java.exe" goto init
+
+echo.
+echo Error: JAVA_HOME is set to an invalid directory. >&2
+echo JAVA_HOME = "%JAVA_HOME%" >&2
+echo Please set the JAVA_HOME variable in your environment to match the >&2
+echo location of your Java installation. >&2
+echo.
+goto error
+
+@REM ==== END VALIDATION ====
+
+:init
+
+@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
+@REM Fallback to current working directory if not found.
+
+set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
+IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
+
+set EXEC_DIR=%CD%
+set WDIR=%EXEC_DIR%
+:findBaseDir
+IF EXIST "%WDIR%"\.mvn goto baseDirFound
+cd ..
+IF "%WDIR%"=="%CD%" goto baseDirNotFound
+set WDIR=%CD%
+goto findBaseDir
+
+:baseDirFound
+set MAVEN_PROJECTBASEDIR=%WDIR%
+cd "%EXEC_DIR%"
+goto endDetectBaseDir
+
+:baseDirNotFound
+set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
+cd "%EXEC_DIR%"
+
+:endDetectBaseDir
+
+IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
+
+@setlocal EnableExtensions EnableDelayedExpansion
+for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
+@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
+
+:endReadAdditionalConfig
+
+SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
+set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
+set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
+
+set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
+
+FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
+    IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
+)
+
+@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
+@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
+if exist %WRAPPER_JAR% (
+    if "%MVNW_VERBOSE%" == "true" (
+        echo Found %WRAPPER_JAR%
+    )
+) else (
+    if not "%MVNW_REPOURL%" == "" (
+        SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
+    )
+    if "%MVNW_VERBOSE%" == "true" (
+        echo Couldn't find %WRAPPER_JAR%, downloading it ...
+        echo Downloading from: %DOWNLOAD_URL%
+    )
+
+    powershell -Command "&{"^
+		"$webclient = new-object System.Net.WebClient;"^
+		"if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
+		"$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
+		"}"^
+		"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^
+		"}"
+    if "%MVNW_VERBOSE%" == "true" (
+        echo Finished downloading %WRAPPER_JAR%
+    )
+)
+@REM End of extension
+
+@REM Provide a "standardized" way to retrieve the CLI args that will
+@REM work with both Windows and non-Windows executions.
+set MAVEN_CMD_LINE_ARGS=%*
+
+%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
+if ERRORLEVEL 1 goto error
+goto end
+
+:error
+set ERROR_CODE=1
+
+:end
+@endlocal & set ERROR_CODE=%ERROR_CODE%
+
+if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
+@REM check for post script, once with legacy .bat ending and once with .cmd ending
+if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
+if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
+:skipRcPost
+
+@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
+if "%MAVEN_BATCH_PAUSE%" == "on" pause
+
+if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
+
+exit /B %ERROR_CODE%
diff --git a/components/basys.components/pom.xml b/components/basys.components/pom.xml
index 79515eb..6bc6bf7 100644
--- a/components/basys.components/pom.xml
+++ b/components/basys.components/pom.xml
@@ -5,7 +5,7 @@
 	
 	<groupId>org.eclipse.basyx</groupId>
 	<artifactId>basyx.components</artifactId>
-	<version>0.0.1-SNAPSHOT</version>
+	<version>1.0.0</version>
 	<name>BaSyx Components</name>
 
 	<packaging>pom</packaging>
@@ -79,6 +79,8 @@
 						<excludes>
 							<exclude>**/*HTTP*</exclude>
 							<exclude>**/*TCP*</exclude>
+							<!-- Exclude explicit MongoDB tests for CI -->
+							<exclude>**/*MongoDB*</exclude>
 						</excludes>
 					</configuration>
 				</plugin>
@@ -119,14 +121,14 @@
 			<dependency>
 				<groupId>org.eclipse.basyx</groupId>
 				<artifactId>basyx.sdk</artifactId>
-				<version>0.0.1-SNAPSHOT</version>
+				<version>1.0.0</version>
 			</dependency>
 		
 			<!-- BaSyx SDK tests -->
 			<dependency>
 				<groupId>org.eclipse.basyx</groupId>
 				<artifactId>basyx.sdk</artifactId>
-				<version>0.0.1-SNAPSHOT</version>
+				<version>1.0.0</version>
 				<classifier>tests</classifier>
 				<scope>test</scope>
 			</dependency>
diff --git a/components/basyx.tck/.gitignore b/components/basyx.tck/.gitignore
new file mode 100644
index 0000000..e0e5af1
--- /dev/null
+++ b/components/basyx.tck/.gitignore
@@ -0,0 +1,72 @@
+regressiontest/
+
+.classpath
+.project
+
+test.txt
+
+target/
+pom.xml.tag
+pom.xml.releaseBackup
+pom.xml.versionsBackup
+pom.xml.next
+release.properties
+dependency-reduced-pom.xml
+buildNumber.properties
+.mvn/timing.properties
+.mvn/wrapper/maven-wrapper.jar
+.metadata
+bin/
+tmp/
+*.tmp
+*.bak
+*.swp
+*~.nib
+local.properties
+.settings/
+.loadpath
+.recommenders
+
+# External tool builders
+.externalToolBuilders/
+
+# Locally stored "Eclipse launch configurations"
+*.launch
+
+# PyDev specific (Python IDE for Eclipse)
+*.pydevproject
+
+# CDT-specific (C/C++ Development Tooling)
+.cproject
+
+# CDT- autotools
+.autotools
+
+# Java annotation processor (APT)
+.factorypath
+
+# PDT-specific (PHP Development Tools)
+.buildpath
+
+# sbteclipse plugin
+.target
+
+# Tern plugin
+.tern-project
+
+# TeXlipse plugin
+.texlipse
+
+# STS (Spring Tool Suite)
+.springBeans
+
+# Code Recommenders
+.recommenders/
+
+# Annotation Processing
+.apt_generated/
+
+# Scala IDE specific (Scala & Java development for Eclipse)
+.cache-main
+.scala_dependencies
+.worksheet
\ No newline at end of file
diff --git a/components/basyx.tck/basyx.tck.AASServer/pom.xml b/components/basyx.tck/basyx.tck.AASServer/pom.xml
new file mode 100644
index 0000000..f4b0326
--- /dev/null
+++ b/components/basyx.tck/basyx.tck.AASServer/pom.xml
@@ -0,0 +1,58 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.eclipse.basyx</groupId>
+    <artifactId>basyx.tck</artifactId>
+    <version>1.0.0</version>
+  </parent>
+  
+  <artifactId>basyx.tck.AASServer</artifactId>
+  <name>TCK for AAS API</name>
+  <packaging>jar</packaging>
+  
+  <properties>
+		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+	</properties>
+
+	<build>
+		<sourceDirectory>src/main/java</sourceDirectory>
+		<testSourceDirectory>src/test/java</testSourceDirectory>
+
+		<plugins>
+			<plugin>
+		      <artifactId>maven-assembly-plugin</artifactId>
+		      <configuration>
+		       <descriptor>src/main/assembly/assembly.xml</descriptor>
+		        <archive>
+		          <manifest>
+		            <mainClass>org.eclipse.basyx.testsuite.regression.aas.metamodel.AASServerTestApplication</mainClass>
+		          </manifest>
+		        </archive>
+		      </configuration>
+		    </plugin>
+		</plugins>
+	</build>
+  
+  
+  <dependencies>
+		<!-- This component is based on the xmlAAS component -->
+		<dependency>
+			<groupId>org.eclipse.basyx</groupId>
+			<artifactId>basyx.components.AASServer</artifactId>
+			<version>${project.version}</version>
+		</dependency>
+		<!-- BaSyx SDK -->
+		<dependency>
+			<groupId>org.eclipse.basyx</groupId>
+			<artifactId>basyx.sdk</artifactId>
+		</dependency>
+		<!-- BaSyx SDK tests -->
+		<dependency>
+			<groupId>org.eclipse.basyx</groupId>
+			<artifactId>basyx.sdk</artifactId>
+			<classifier>tests</classifier>
+			<scope>test</scope>
+		</dependency>
+	</dependencies>
+</project>
\ No newline at end of file
diff --git a/components/basyx.tck/basyx.tck.AASServer/src/main/assembly/assembly.xml b/components/basyx.tck/basyx.tck.AASServer/src/main/assembly/assembly.xml
new file mode 100644
index 0000000..2a283bf
--- /dev/null
+++ b/components/basyx.tck/basyx.tck.AASServer/src/main/assembly/assembly.xml
@@ -0,0 +1,28 @@
+<assembly
+    xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 http://maven.apache.org/xsd/assembly-1.1.3.xsd">
+    <id>fat-tests</id>
+    <formats>
+        <format>jar</format>
+    </formats>
+    <includeBaseDirectory>false</includeBaseDirectory>
+    <dependencySets>
+        <dependencySet>
+            <outputDirectory>/</outputDirectory>
+            <useProjectArtifact>true</useProjectArtifact>
+            <unpack>true</unpack>
+            <scope>test</scope>
+        </dependencySet>
+    </dependencySets>
+    <fileSets>
+        <fileSet>
+            <directory>${project.build.directory}/test-classes</directory>
+            <outputDirectory>/</outputDirectory>
+            <includes>
+                <include>**/*.class</include>
+            </includes>
+            <useDefaultExcludes>true</useDefaultExcludes>
+        </fileSet>
+    </fileSets>
+</assembly>
\ No newline at end of file
diff --git a/components/basyx.tck/basyx.tck.AASServer/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/AASAggregatorSuiteWithDefinedURL.java b/components/basyx.tck/basyx.tck.AASServer/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/AASAggregatorSuiteWithDefinedURL.java
new file mode 100644
index 0000000..7ce61cb
--- /dev/null
+++ b/components/basyx.tck/basyx.tck.AASServer/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/AASAggregatorSuiteWithDefinedURL.java
@@ -0,0 +1,173 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.aas.metamodel;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.basyx.aas.aggregator.api.IAASAggregator;
+import org.eclipse.basyx.aas.aggregator.proxy.AASAggregatorProxy;
+import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
+import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.connected.ConnectedAssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+import org.eclipse.basyx.aas.registration.memory.InMemoryRegistry;
+import org.eclipse.basyx.components.aas.aasx.AASXPackageManager;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.connected.ConnectedSubmodel;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.eclipse.basyx.support.bundle.AASBundle;
+import org.eclipse.basyx.testsuite.regression.aas.aggregator.AASAggregatorSuite;
+import org.junit.Test;
+
+/**
+ * Instantiate a concrete test suite for AASAggregator from the abstract test
+ * suite.
+ * 
+ * @author zhangzai
+ *
+ */
+public class AASAggregatorSuiteWithDefinedURL extends AASAggregatorSuite {
+
+	public static String url;
+	private static final String aas1Id = "smart.festo.com/demo/aas/1/1/454576463545648365874";
+	private static final String aas2Id = "www.admin-shell.io/aas-sample/1/1";
+
+	/**
+	 * A bundle of AAS extracted from the AASX package
+	 */
+	private Map<String, IAssetAdministrationShell> aasMap = new HashMap<>();
+	private Set<AASBundle> aasBundles;
+
+	@Override
+	protected IAASAggregator getAggregator() {
+		return new AASAggregatorProxy(url);
+	}
+
+	/**
+	 * Fetch AAS from AASX package and create them on the server
+	 * 
+	 * @throws Exception
+	 */
+	@Test
+	public void testMetaModel() throws Exception {
+		// First argument is the server URL
+		String serverHost = url;
+
+		// Create a in-memory registry
+		InMemoryRegistry registry = new InMemoryRegistry();
+
+		ConnectedAssetAdministrationShellManager manager = new ConnectedAssetAdministrationShellManager(registry);
+
+		// Get the AAS Bundle
+		// Instantiate the aasx package manager
+		String aasxPath = "aasx/01_Festo.aasx";
+		AASXPackageManager packageManager = new AASXPackageManager(aasxPath);
+
+		// Unpack the files referenced by the aas
+		packageManager.unzipRelatedFiles();
+
+		// Retrieve the aas from the package
+		aasBundles = packageManager.retrieveAASBundles();
+
+		// Create the AAS on the server
+		aasBundles.forEach((x) -> {
+			// Get the ID of the AAS
+			AssetAdministrationShell aas = (AssetAdministrationShell) x.getAAS();
+			IIdentifier aasid = aas.getIdentification();
+
+			// Create the AAS on the server
+			manager.createAAS(aas, serverHost);
+			aasMap.put(aasid.getId(), aas);
+
+			// create the Submodels
+			x.getSubmodels().forEach(y -> {
+				manager.createSubmodel(aasid, (Submodel) y);
+			});
+
+		});
+
+		// Check the created AAS from the aasx package
+		checkAAS(aas1Id, manager);
+		checkAAS(aas2Id, manager);
+	}
+
+	/**
+	 * Check whether the aas is created correctly
+	 * 
+	 * @param manager
+	 * @throws Exception
+	 */
+	private void checkAAS(String aasid, ConnectedAssetAdministrationShellManager manager) throws Exception {
+		IIdentifier aasIdentifier = new Identifier(IdentifierType.IRI, aasid);
+
+		// Get the created AAS from the server
+		IAASAggregator aasAggregator = getAggregator();
+		ConnectedAssetAdministrationShell remoteAas = manager.retrieveAAS(aasIdentifier);
+
+		// Get the expected aas from aas bundle
+		IAssetAdministrationShell expected = aasMap.get(aasid);
+
+		// compare the both aas
+		AssetAdministrationShell localCopy = remoteAas.getLocalCopy();
+		
+		assertEquals(expected.getIdentification(), localCopy.getIdentification());
+		assertEquals(expected.getAsset(), localCopy.getAsset());
+		assertEquals(expected.getIdShort(), localCopy.getIdShort());
+		assertEquals(expected.getIdentification(), localCopy.getIdentification());
+		assertEquals(expected.getDescription(), localCopy.getDescription());
+		
+		// References can be built in different ways, therefore a direct comparison is not possible
+		assertEquals(expected.getSubmodelReferences().size(), localCopy.getSubmodelReferences().size());
+
+		// Get submodels from bundle
+		AASBundle aasBundle = aasBundles.stream().filter(b -> b.getAAS().getIdentification().getId().equals(aasIdentifier.getId())).findFirst().get();
+		aasBundle.getSubmodels().forEach(expectedSm -> {
+				Map<String, ISubmodel> sms = manager.retrieveSubmodels(aasIdentifier);
+				// get submodel from remote
+				ConnectedSubmodel remote = (ConnectedSubmodel) sms.get(expectedSm.getIdShort());
+				// compare the both submodels
+				checkSM(expectedSm, remote.getLocalCopy());
+			});
+
+		
+		// Delete the AAS
+		aasAggregator.deleteAAS(aasIdentifier);
+
+	}
+	
+	/**
+	 * Checks whether two Submodels are equal
+	 * 
+	 * @param expected
+	 * @param actual
+	 */
+	private void checkSM(ISubmodel expected, ISubmodel actual) {
+		assertEquals(expected.getIdShort(), actual.getIdShort());
+		assertEquals(expected.getIdentification(), actual.getIdentification());
+		assertEquals(expected.getDescription(), actual.getDescription());
+		assertEquals(expected.getReference(), actual.getReference());
+		assertEquals(expected.getQualifiers(), actual.getQualifiers());
+		assertEquals(expected.getSubmodelElements().size(), actual.getSubmodelElements().size());
+		
+		for(String id: expected.getSubmodelElements().keySet()) {
+			assertTrue(actual.getSubmodelElements().containsKey(id));
+		}
+	}
+
+
+}
diff --git a/components/basyx.tck/basyx.tck.AASServer/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/AASServerTestApplication.java b/components/basyx.tck/basyx.tck.AASServer/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/AASServerTestApplication.java
new file mode 100644
index 0000000..37ad199
--- /dev/null
+++ b/components/basyx.tck/basyx.tck.AASServer/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/AASServerTestApplication.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.aas.metamodel;
+
+import org.junit.internal.TextListener;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Result;
+
+/**
+ * Application for testing an AAS server The first argument is the server host +
+ * context-path The application creates an internal registry, then extract the
+ * AASs from an existing AASX package. After that, it create the AASs and their
+ * sub-models on the server.
+ * 
+ * @author zhangzai
+ *
+ */
+public class AASServerTestApplication {
+
+
+	public static void main(String[] args) throws Exception {
+		
+		// First argument is the inserted url
+		String url = args[0];
+		AASAggregatorSuiteWithDefinedURL.url = url;
+
+
+
+		// Run junit test in a java application
+		JUnitCore junit = new JUnitCore();
+		junit.addListener(new TextListener(System.out));
+
+		
+		Result result = junit.run(AASAggregatorSuiteWithDefinedURL.class);
+
+		System.out.println("Finished. Result: Failures: " +
+				result.getFailureCount() + ". Ignored: " +
+				result.getIgnoreCount() + ". Tests run: " +
+				result.getRunCount() + ". Time: " +
+				result.getRunTime() + "ms.");
+
+	}
+
+}
diff --git a/components/basyx.tck/basyx.tck.registry/pom.xml b/components/basyx.tck/basyx.tck.registry/pom.xml
new file mode 100644
index 0000000..b609541
--- /dev/null
+++ b/components/basyx.tck/basyx.tck.registry/pom.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0"?>
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" 
+	xmlns="http://maven.apache.org/POM/4.0.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.eclipse.basyx</groupId>
+    <artifactId>basyx.tck</artifactId>
+    <version>1.0.0</version>
+  </parent>
+  
+  <artifactId>basyx.tck.registry</artifactId>
+  
+  <name>TCK for AASRegistry</name>
+  <url>http://maven.apache.org</url>
+  <packaging>jar</packaging>
+
+	<properties>
+		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+	</properties>
+
+	<build>
+		<sourceDirectory>src/main/java</sourceDirectory>
+		<testSourceDirectory>src/test/java</testSourceDirectory>
+
+		<plugins>
+			<plugin>
+		      <artifactId>maven-assembly-plugin</artifactId>
+		      <configuration>
+		       <descriptor>src/main/assembly/assembly.xml</descriptor>
+		        <archive>
+		          <manifest>
+		            <mainClass>org.eclipse.basyx.testsuite.regression.aas.registration.RegistryProviderTestApplication</mainClass>
+		          </manifest>
+		        </archive>
+		      </configuration>
+		    </plugin>
+		</plugins>
+	</build>
+
+	<dependencies>
+		<!-- BaSyx SDK -->
+		<dependency>
+			<groupId>org.eclipse.basyx</groupId>
+			<artifactId>basyx.sdk</artifactId>
+		</dependency>
+		<!-- BaSyx SDK tests -->
+		<dependency>
+			<groupId>org.eclipse.basyx</groupId>
+			<artifactId>basyx.sdk</artifactId>
+			<classifier>tests</classifier>
+			<scope>test</scope>
+		</dependency>
+	</dependencies>
+</project>
diff --git a/components/basyx.tck/basyx.tck.registry/src/main/assembly/assembly.xml b/components/basyx.tck/basyx.tck.registry/src/main/assembly/assembly.xml
new file mode 100644
index 0000000..2a283bf
--- /dev/null
+++ b/components/basyx.tck/basyx.tck.registry/src/main/assembly/assembly.xml
@@ -0,0 +1,28 @@
+<assembly
+    xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 http://maven.apache.org/xsd/assembly-1.1.3.xsd">
+    <id>fat-tests</id>
+    <formats>
+        <format>jar</format>
+    </formats>
+    <includeBaseDirectory>false</includeBaseDirectory>
+    <dependencySets>
+        <dependencySet>
+            <outputDirectory>/</outputDirectory>
+            <useProjectArtifact>true</useProjectArtifact>
+            <unpack>true</unpack>
+            <scope>test</scope>
+        </dependencySet>
+    </dependencySets>
+    <fileSets>
+        <fileSet>
+            <directory>${project.build.directory}/test-classes</directory>
+            <outputDirectory>/</outputDirectory>
+            <includes>
+                <include>**/*.class</include>
+            </includes>
+            <useDefaultExcludes>true</useDefaultExcludes>
+        </fileSet>
+    </fileSets>
+</assembly>
\ No newline at end of file
diff --git a/components/basyx.tck/basyx.tck.registry/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/RegistryProviderSuiteWithDefinedURL.java b/components/basyx.tck/basyx.tck.registry/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/RegistryProviderSuiteWithDefinedURL.java
new file mode 100644
index 0000000..0d4b242
--- /dev/null
+++ b/components/basyx.tck/basyx.tck.registry/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/RegistryProviderSuiteWithDefinedURL.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.aas.registration;
+
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
+import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
+
+/**
+ * Instantiate a concrete test class for the abstract test suite
+ * 
+ * @author zhangzai
+ *
+ */
+public class RegistryProviderSuiteWithDefinedURL extends TestRegistryProviderSuite {
+
+	public static String url;// for example: "http://localhost:4999/";
+
+	@Override
+	protected IAASRegistry getRegistryService() {
+		return new AASRegistryProxy(url);
+	}
+
+	@Override
+	public void testDeleteByAssetIdCall() {
+		// Not within official specification
+	}
+
+	@Override
+	public void testDeleteWithAssetExtension() {
+		// Not within official specification
+	}
+
+}
diff --git a/components/basyx.tck/basyx.tck.registry/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/RegistryProviderTestApplication.java b/components/basyx.tck/basyx.tck.registry/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/RegistryProviderTestApplication.java
new file mode 100644
index 0000000..5cb66e8
--- /dev/null
+++ b/components/basyx.tck/basyx.tck.registry/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/RegistryProviderTestApplication.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.aas.registration;
+
+import org.junit.internal.TextListener;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Result;
+
+/**
+ * The main class that executes the concrete test suite of the registry provider
+ * 
+ * @author zhangzai
+ *
+ */
+public class RegistryProviderTestApplication {
+
+
+	/**
+	 * Run the test suite of the registry provider with inserted url
+	 * 
+	 * @param args - URL inserted by the user
+	 */
+	public static void main(String[] args) {
+		// First argument is the inserted url
+		String url = args[0];
+
+		// Run the junit tests
+		JUnitCore junit = new JUnitCore();
+		junit.addListener(new TextListener(System.out));
+
+		RegistryProviderSuiteWithDefinedURL.url = url;
+		Result result = junit.run(RegistryProviderSuiteWithDefinedURL.class);
+
+		System.out.println("Finished. Result: Failures: " +
+				result.getFailureCount() + ". Ignored: " +
+				result.getIgnoreCount() + ". Tests run: " +
+				result.getRunCount() + ". Time: " +
+				result.getRunTime() + "ms.");
+	}
+}
diff --git a/components/basyx.tck/pom.xml b/components/basyx.tck/pom.xml
new file mode 100644
index 0000000..9abf62a
--- /dev/null
+++ b/components/basyx.tck/pom.xml
@@ -0,0 +1,126 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>org.eclipse.basyx</groupId>
+  <artifactId>basyx.tck</artifactId>
+  <version>1.0.0</version>
+  
+  
+  <packaging>pom</packaging>
+
+	<properties>
+		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+	</properties>
+	
+	<!-- Includes all components in this project as separated modules -->
+	<modules>
+		<module>basyx.tck.AASServer</module>
+		<module>basyx.tck.registry</module>
+	</modules>
+	
+	
+	<build>
+		<!-- Specifies plugin settings that are common for all submodules -->
+		<pluginManagement>
+			<plugins>
+				<!-- Compile Java sources using Java 8 -->
+				<plugin>
+					<groupId>org.apache.maven.plugins</groupId>
+					<artifactId>maven-compiler-plugin</artifactId>
+					<version>3.8.1</version>
+					<configuration>
+						<source>1.8</source>
+						<target>1.8</target>
+					</configuration>
+				</plugin>
+	
+				<!-- Attach sources to jar file -->
+				<plugin>
+					<groupId>org.apache.maven.plugins</groupId>
+					<artifactId>maven-source-plugin</artifactId>
+					<version>3.2.1</version>
+					<executions>
+						<execution>
+							<id>attach-sources</id>
+							<goals>
+								<goal>jar-no-fork</goal>
+							</goals>
+						</execution>
+					</executions>
+				</plugin>
+				
+				<!-- Generate separate jar for tests and exclude logback.xml from generated jars -->
+				<plugin>
+					<groupId>org.apache.maven.plugins</groupId>
+					<artifactId>maven-jar-plugin</artifactId>
+					<version>3.1.1</version>
+					<configuration>
+						<excludes>
+							<exclude>**/logback.xml</exclude>
+						</excludes>
+					</configuration>
+					<executions>
+						<execution>
+							<goals>
+								<goal>test-jar</goal>
+							</goals>
+						</execution>
+					</executions>
+				</plugin>
+		
+				<!-- Run unit tests -->
+				<plugin>
+					<groupId>org.apache.maven.plugins</groupId>
+					<artifactId>maven-surefire-plugin</artifactId>
+					<version>3.0.0-M3</version>
+				</plugin>
+	
+				<!-- Run integration tests -->
+				<plugin>
+					<groupId>org.apache.maven.plugins</groupId>
+					<artifactId>maven-failsafe-plugin</artifactId>
+					<version>3.0.0-M3</version>
+					<executions>
+						<execution>
+							<goals>
+								<goal>integration-test</goal>
+								<goal>verify</goal>
+							</goals>
+						</execution>
+					</executions>
+				</plugin> 
+			</plugins>
+		</pluginManagement>
+	</build>
+	
+	<!-- Every submodule depends on these dependencies -->
+	<dependencies>
+		<!-- JUnit 4 for running JUnit tests -->
+		<dependency>
+			<groupId>junit</groupId>
+			<artifactId>junit</artifactId>
+			<version>4.12</version>
+			<scope>test</scope>
+		</dependency>
+	</dependencies>
+	
+	<!-- Specifies dependency settings for all submodules using these dependencies -->
+	<dependencyManagement>
+		<dependencies>
+			<!-- BaSyx SDK -->
+			<dependency>
+				<groupId>org.eclipse.basyx</groupId>
+				<artifactId>basyx.sdk</artifactId>
+				<version>1.0.0</version>
+			</dependency>
+			<!-- BaSyx SDK tests -->
+			<dependency>
+				<groupId>org.eclipse.basyx</groupId>
+				<artifactId>basyx.sdk</artifactId>
+				<version>1.0.0</version>
+				<classifier>tests</classifier>
+				<scope>test</scope>
+			</dependency>
+		</dependencies>
+	</dependencyManagement>
+</project>
\ No newline at end of file
diff --git a/examples/.mvn/wrapper/MavenWrapperDownloader.java b/examples/.mvn/wrapper/MavenWrapperDownloader.java
new file mode 100644
index 0000000..e76d1f3
--- /dev/null
+++ b/examples/.mvn/wrapper/MavenWrapperDownloader.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2007-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import java.net.*;
+import java.io.*;
+import java.nio.channels.*;
+import java.util.Properties;
+
+public class MavenWrapperDownloader {
+
+    private static final String WRAPPER_VERSION = "0.5.6";
+    /**
+     * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided.
+     */
+    private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/"
+        + WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar";
+
+    /**
+     * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to
+     * use instead of the default one.
+     */
+    private static final String MAVEN_WRAPPER_PROPERTIES_PATH =
+            ".mvn/wrapper/maven-wrapper.properties";
+
+    /**
+     * Path where the maven-wrapper.jar will be saved to.
+     */
+    private static final String MAVEN_WRAPPER_JAR_PATH =
+            ".mvn/wrapper/maven-wrapper.jar";
+
+    /**
+     * Name of the property which should be used to override the default download url for the wrapper.
+     */
+    private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl";
+
+    public static void main(String args[]) {
+        System.out.println("- Downloader started");
+        File baseDirectory = new File(args[0]);
+        System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath());
+
+        // If the maven-wrapper.properties exists, read it and check if it contains a custom
+        // wrapperUrl parameter.
+        File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH);
+        String url = DEFAULT_DOWNLOAD_URL;
+        if(mavenWrapperPropertyFile.exists()) {
+            FileInputStream mavenWrapperPropertyFileInputStream = null;
+            try {
+                mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile);
+                Properties mavenWrapperProperties = new Properties();
+                mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream);
+                url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url);
+            } catch (IOException e) {
+                System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'");
+            } finally {
+                try {
+                    if(mavenWrapperPropertyFileInputStream != null) {
+                        mavenWrapperPropertyFileInputStream.close();
+                    }
+                } catch (IOException e) {
+                    // Ignore ...
+                }
+            }
+        }
+        System.out.println("- Downloading from: " + url);
+
+        File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH);
+        if(!outputFile.getParentFile().exists()) {
+            if(!outputFile.getParentFile().mkdirs()) {
+                System.out.println(
+                        "- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'");
+            }
+        }
+        System.out.println("- Downloading to: " + outputFile.getAbsolutePath());
+        try {
+            downloadFileFromURL(url, outputFile);
+            System.out.println("Done");
+            System.exit(0);
+        } catch (Throwable e) {
+            System.out.println("- Error downloading");
+            e.printStackTrace();
+            System.exit(1);
+        }
+    }
+
+    private static void downloadFileFromURL(String urlString, File destination) throws Exception {
+        if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) {
+            String username = System.getenv("MVNW_USERNAME");
+            char[] password = System.getenv("MVNW_PASSWORD").toCharArray();
+            Authenticator.setDefault(new Authenticator() {
+                @Override
+                protected PasswordAuthentication getPasswordAuthentication() {
+                    return new PasswordAuthentication(username, password);
+                }
+            });
+        }
+        URL website = new URL(urlString);
+        ReadableByteChannel rbc;
+        rbc = Channels.newChannel(website.openStream());
+        FileOutputStream fos = new FileOutputStream(destination);
+        fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
+        fos.close();
+        rbc.close();
+    }
+
+}
diff --git a/examples/.mvn/wrapper/maven-wrapper.jar b/examples/.mvn/wrapper/maven-wrapper.jar
new file mode 100644
index 0000000..2cc7d4a
--- /dev/null
+++ b/examples/.mvn/wrapper/maven-wrapper.jar
Binary files differ
diff --git a/examples/.mvn/wrapper/maven-wrapper.properties b/examples/.mvn/wrapper/maven-wrapper.properties
new file mode 100644
index 0000000..642d572
--- /dev/null
+++ b/examples/.mvn/wrapper/maven-wrapper.properties
@@ -0,0 +1,2 @@
+distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip
+wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar
diff --git a/examples/basys.examples/examples/org/eclipse/basyx/examples/snippets/undoc/aas/embedhttp/EmbeddedHTTP.java b/examples/basys.examples/examples/org/eclipse/basyx/examples/snippets/undoc/aas/embedhttp/EmbeddedHTTP.java
index e32c767..ba6bb8d 100644
--- a/examples/basys.examples/examples/org/eclipse/basyx/examples/snippets/undoc/aas/embedhttp/EmbeddedHTTP.java
+++ b/examples/basys.examples/examples/org/eclipse/basyx/examples/snippets/undoc/aas/embedhttp/EmbeddedHTTP.java
@@ -1,14 +1,23 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.examples.snippets.undoc.aas.embedhttp;
 
 
 import static org.junit.Assert.assertTrue;
 
 import org.eclipse.basyx.aas.api.resources.ISingleProperty;
-import org.eclipse.basyx.aas.api.resources.ISubModel;
+import org.eclipse.basyx.aas.api.resources.ISubmodel;
 import org.eclipse.basyx.aas.backend.connected.ConnectedAssetAdministrationShellManager;
 import org.eclipse.basyx.aas.backend.connector.http.HTTPConnectorProvider;
 import org.eclipse.basyx.aas.metamodel.factory.MetaModelElementFactory;
-import org.eclipse.basyx.aas.metamodel.hashmap.aas.SubModel;
+import org.eclipse.basyx.aas.metamodel.hashmap.aas.Submodel;
 import org.eclipse.basyx.aas.metamodel.hashmap.aas.submodelelement.property.Property;
 import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
 import org.eclipse.basyx.vab.core.VABConnectionManager;
@@ -52,7 +61,7 @@
 	/**
 	 * Example sub model. This example sub model is created with the BaSyx SDK factory and defines the AAS meta model properties
 	 */
-	static class SampleSubModel extends SubModel {
+	static class SampleSubmodel extends Submodel {
 		
 		/**
 		 * Version number of serialized instance
@@ -64,7 +73,7 @@
 		 * 
 		 * This sub model contains static properties, i.e. properties that have a static value assigned.
 		 */
-		public SampleSubModel() {
+		public SampleSubmodel() {
 			// Create factory that helps with property creation
 			// - This factory creates sub model properties and ensures presence of all meta data
 			MetaModelElementFactory fac = new MetaModelElementFactory();
@@ -83,20 +92,20 @@
 	/**
 	 * Create sub model
 	 */
-	public void createSubModel() {
+	public void createSubmodel() {
 		// Server connections
 		// - Connect to sub model. Connecting to a sub model by its ID is discouraged, because a sub 
 		//   model ID is not necessarily unique outside the scope of its AAS. If users want to connect
 		//   directly to sub models, the registry needs to support this, and unique identifies (as here)
 		//   must be used. For portability, users should connect to sub models instead via an AAS ID and 
 		//   sub model ID tuple, as illustrated in the registry examples. 
-		VABElementProxy connSubModel1 = this.connManager.connectToVABElement(STATUS_SM);
+		VABElementProxy connSubmodel1 = this.connManager.connectToVABElement(STATUS_SM);
 
 		// Instantiate sub model
-		SubModel submodel = new SampleSubModel();
+		Submodel submodel = new SampleSubmodel();
 
 		// Transfer sub model to server
-		connSubModel1.createElement("aas/submodels/" + STATUS_SM, submodel);		
+		connSubmodel1.createElement("aas/submodels/" + STATUS_SM, submodel);		
 	}
 	
 	
@@ -109,7 +118,7 @@
 		// Create and connect SDK connector
 		ConnectedAssetAdministrationShellManager manager = new ConnectedAssetAdministrationShellManager(connManager);
 		// - Retrieve sub model
-		ISubModel subModel = manager.retrieveSM(STATUS_SM);
+		ISubmodel subModel = manager.retrieveSM(STATUS_SM);
 
 		// Read sub model properties
 		String smId     = subModel.getId();
@@ -140,12 +149,12 @@
 	@Test
 	public void runTest() throws Exception {
 		// Create and start embedded HTTP server
-		EmbeddedHTTPServer server = new EmbeddedHTTPSubModelServer("/BaSys/1.0/embedHTTP", new VABLambdaProvider(new SampleSubModel()));
+		EmbeddedHTTPServer server = new EmbeddedHTTPSubmodelServer("/BaSys/1.0/embedHTTP", new VABLambdaProvider(new SampleSubmodel()));
 		// - Start server
 		server.start();
 		
 		// Connect to server, create sub model, and test access to sub model
-		createSubModel();
+		createSubmodel();
 		testCRUDAAS();
 
 		// Stop HTTP server
diff --git a/examples/basys.examples/examples/org/eclipse/basyx/examples/snippets/undoc/aas/embedhttp/EmbeddedHTTPServer.java b/examples/basys.examples/examples/org/eclipse/basyx/examples/snippets/undoc/aas/embedhttp/EmbeddedHTTPServer.java
index bb690df..505018d 100644
--- a/examples/basys.examples/examples/org/eclipse/basyx/examples/snippets/undoc/aas/embedhttp/EmbeddedHTTPServer.java
+++ b/examples/basys.examples/examples/org/eclipse/basyx/examples/snippets/undoc/aas/embedhttp/EmbeddedHTTPServer.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.examples.snippets.undoc.aas.embedhttp;
 
 import java.io.IOException;
diff --git a/examples/basys.examples/examples/org/eclipse/basyx/examples/snippets/undoc/aas/embedhttp/EmbeddedHTTPSubModelServer.java b/examples/basys.examples/examples/org/eclipse/basyx/examples/snippets/undoc/aas/embedhttp/EmbeddedHTTPSubModelServer.java
index af110b2..5a8ca5b 100644
--- a/examples/basys.examples/examples/org/eclipse/basyx/examples/snippets/undoc/aas/embedhttp/EmbeddedHTTPSubModelServer.java
+++ b/examples/basys.examples/examples/org/eclipse/basyx/examples/snippets/undoc/aas/embedhttp/EmbeddedHTTPSubModelServer.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.examples.snippets.undoc.aas.embedhttp;
 
 import java.util.HashMap;
@@ -14,13 +23,13 @@
  * @author kuhn
  *
  */
-public class EmbeddedHTTPSubModelServer extends EmbeddedHTTPServer {
+public class EmbeddedHTTPSubmodelServer extends EmbeddedHTTPServer {
 
 	
 	/**
 	 * Constructor
 	 */
-	public EmbeddedHTTPSubModelServer(String context, IModelProvider provider) {
+	public EmbeddedHTTPSubmodelServer(String context, IModelProvider provider) {
 		// Invoke base constructor
 		super(context, provider);
 
diff --git a/examples/basys.examples/pom.xml b/examples/basys.examples/pom.xml
index 9091809..e47a66e 100644
--- a/examples/basys.examples/pom.xml
+++ b/examples/basys.examples/pom.xml
@@ -2,7 +2,7 @@
   <modelVersion>4.0.0</modelVersion>
   <groupId>org.eclipse.basyx</groupId>
   <artifactId>basyx.examples</artifactId>
-  <version>0.0.1-SNAPSHOT</version>
+  <version>1.0.0</version>
   <packaging>jar</packaging>
   <name>BaSyx Examples</name>
   
@@ -11,18 +11,6 @@
   		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
 	</properties>
 	
- 	<repositories>
-		<repository>
-			<id>mule</id>
-			<name>Mule Repository</name>
-			<url>https://repository.mulesoft.org/nexus/content/groups/public/</url>
-			<layout>default</layout>
-			<snapshots>
-				<enabled>false</enabled>
-			</snapshots>
-		</repository>
-	</repositories>
-  
    <build>
     <sourceDirectory>src/main/java</sourceDirectory>
     <testSourceDirectory>src/test/java</testSourceDirectory>
@@ -111,189 +99,33 @@
 			<artifactId>junit</artifactId>
 			<version>4.12</version>
 		</dependency>
-		
-		<!-- https://mvnrepository.com/artifact/javax.ws.rs/javax.ws.rs-api -->
-		<!-- https://mvnrepository.com/artifact/org.glassfish.jersey.core/jersey-client -->
-		<!-- https://mvnrepository.com/artifact/javax.servlet/servlet-api -->
-		<!-- https://mvnrepository.com/artifact/org.apache.tomcat/tomcat-catalina 
-			(Tomcat 8, not 9) -->
-		<dependency>
-			<groupId>org.json</groupId>
-			<artifactId>json</artifactId>
-			<version>20180813</version>
-			<!-- <scope>provided</scope> -->
-		</dependency>
-		<!-- Dependencies removed from Classpath -->
-		<!-- https://mvnrepository.com/artifact/org.postgresql/postgresql -->
-		<dependency>
-			<groupId>org.postgresql</groupId>
-			<artifactId>postgresql</artifactId>
-			<version>42.2.2</version>
-		</dependency>
-		<!-- https://mvnrepository.com/artifact/org.glassfish.hk2.external/aopalliance-repackaged -->
-		<dependency>
-			<groupId>org.glassfish.hk2.external</groupId>
-			<artifactId>aopalliance-repackaged</artifactId>
-			<version>2.5.0-b42</version>
-		</dependency>
-		<!-- https://mvnrepository.com/artifact/javax.enterprise/cdi-api -->
-		<dependency>
-			<groupId>javax.enterprise</groupId>
-			<artifactId>cdi-api</artifactId>
-			<version>2.0</version>
-			<scope>provided</scope>
-		</dependency>
-		<!-- https://mvnrepository.com/artifact/javax.el/el-api -->
-		<dependency>
-			<groupId>javax.el</groupId>
-			<artifactId>el-api</artifactId>
-			<version>2.2</version>
-		</dependency>
-		<!-- https://mvnrepository.com/artifact/org.glassfish.hk2/hk2-api -->
-		<dependency>
-			<groupId>org.glassfish.hk2</groupId>
-			<artifactId>hk2-api</artifactId>
-			<version>2.5.0</version>
-		</dependency>
-		<!-- https://mvnrepository.com/artifact/javassist/javassist -->
-		<dependency>
-			<groupId>javassist</groupId>
-			<artifactId>javassist</artifactId>
-			<version>3.12.1.GA</version>
-		</dependency>
-		<!-- https://mvnrepository.com/artifact/javax.annotation/javax.annotation-api -->
-		<!-- https://mvnrepository.com/artifact/javax.inject/javax.inject -->
-		<dependency>
-			<groupId>javax.inject</groupId>
-			<artifactId>javax.inject</artifactId>
-			<version>1</version>
-		</dependency>
-		<!-- https://mvnrepository.com/artifact/javax.json/javax.json-api -->
-		<dependency>
-			<groupId>javax.json</groupId>
-			<artifactId>javax.json-api</artifactId>
-			<version>1.0</version>
-		</dependency>
-		<!-- https://mvnrepository.com/artifact/javax.xml.bind/jaxb-api -->
-		<dependency>
-			<groupId>javax.xml.bind</groupId>
-			<artifactId>jaxb-api</artifactId>
-			<version>2.3.0</version>
-		</dependency>
-		<!-- https://mvnrepository.com/artifact/org.jboss.spec.javax.interceptor/jboss-interceptors-api_1.1_spec -->
-		<dependency>
-			<groupId>org.jboss.spec.javax.interceptor</groupId>
-			<artifactId>jboss-interceptors-api_1.1_spec</artifactId>
-			<version>1.0.1.Final</version>
-		</dependency>
-		<!-- https://mvnrepository.com/artifact/javax.annotation/javax.annotation-api -->
-		<dependency>
-			<groupId>javax.annotation</groupId>
-			<artifactId>javax.annotation-api</artifactId>
-			<version>1.3.2</version>
-		</dependency>
-		<!-- https://mvnrepository.com/artifact/org.osgi/org.osgi.core -->
-		<dependency>
-			<groupId>org.osgi</groupId>
-			<artifactId>org.osgi.core</artifactId>
-			<version>4.2.0</version>
-			<scope>provided</scope>
-		</dependency>
-		<!-- https://mvnrepository.com/artifact/org.glassfish.hk2/osgi-resource-locator -->
-		<dependency>
-			<groupId>org.glassfish.hk2</groupId>
-			<artifactId>osgi-resource-locator</artifactId>
-			<version>1.0.1</version>
-		</dependency>
-		<!-- https://mvnrepository.com/artifact/javax.persistence/persistence-api -->
-		<dependency>
-			<groupId>javax.persistence</groupId>
-			<artifactId>persistence-api</artifactId>
-			<version>1.0.2</version>
-		</dependency>
-		<!-- https://mvnrepository.com/artifact/javax.validation/validation-api -->
-		<dependency>
-			<groupId>javax.validation</groupId>
-			<artifactId>validation-api</artifactId>
-			<version>2.0.1.Final</version>
-		</dependency>
-		<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
-		<dependency>
-			<groupId>javax.servlet</groupId>
-			<artifactId>javax.servlet-api</artifactId>
-			<version>3.1.0</version>
-			<scope>provided</scope>
-		</dependency>
-
-		<!-- https://mvnrepository.com/artifact/org.eclipse/yasson -->
-		<dependency>
-			<groupId>org.eclipse</groupId>
-			<artifactId>yasson</artifactId>
-			<version>1.0.2</version>
-		</dependency>
-
-		<!-- https://mvnrepository.com/artifact/javax.xml.xquery/xqj-api (Add from 
-			local repository because jar cannot be found on maven central -->
-		<dependency>
-			<groupId>javax.xml.xquery</groupId>
-			<artifactId>xqj-api</artifactId>
-			<version>1.0</version>
-		</dependency>
-
-		<!-- https://mvnrepository.com/artifact/net.sf.saxon/saxon-xqj -->
-		<!-- <dependency> <groupId>net.sf.saxon</groupId> <artifactId>saxon-xqj</artifactId> 
-			<version>9.x</version> </dependency> -->
-
-		<!-- https://mvnrepository.com/artifact/net.sf.saxon/saxon-xqj -->
-		<dependency>
-			<groupId>net.sf.saxon</groupId>
-			<artifactId>saxon-xqj</artifactId>
-			<version>8.9.0.4</version>
-		</dependency>
-
-
-		<!-- https://mvnrepository.com/artifact/net.sf.saxon/Saxon-HE -->
-		<dependency>
-			<groupId>net.sf.saxon</groupId>
-			<artifactId>Saxon-HE</artifactId>
-			<version>9.5.1-5</version>
-		</dependency>
-
-
-		<dependency>
-			<groupId>com.google.code.gson</groupId>
-			<artifactId>gson</artifactId>
-			<version>2.8.5</version>
-		</dependency>
-
 				
 		<!-- Add BaSys components from local repository. Maven build of SDK must generate a jar and place it into the repository to update -->
 		<dependency>
 			<groupId>org.eclipse.basyx</groupId>
 			<artifactId>basyx.components.lib</artifactId>
-			<version>0.0.1-SNAPSHOT</version>
+			<version>1.0.0</version>
 		</dependency>
 		
 		<!-- Add explicit SQLRegistry dependency -->
 		<dependency>
 			<groupId>org.eclipse.basyx</groupId>
-			<artifactId>basyx.components.sqlregistry</artifactId>
-			<version>0.0.1-SNAPSHOT</version>
+			<artifactId>basyx.components.registry</artifactId>
+			<version>1.0.2</version>
 		</dependency>
-		
 				
 		<!-- Add explicit AAS Server component dependency -->
 		<dependency>
 			<groupId>org.eclipse.basyx</groupId>
 			<artifactId>basyx.components.AASServer</artifactId>
-			<version>0.0.1-SNAPSHOT</version>
+			<version>1.0.0</version>
 		</dependency>
 		
 		<!-- Adds additional classes of the BaSys SDK for tests -->
 		<dependency>
 			<groupId>org.eclipse.basyx</groupId>
 			<artifactId>basyx.sdk</artifactId>
-			<version>0.0.1-SNAPSHOT</version>
+			<version>1.0.0</version>
 			<classifier>tests</classifier>
 			<scope>test</scope>
 		</dependency>
diff --git a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/deployment/BaSyxDeployment.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/deployment/BaSyxDeployment.java
deleted file mode 100644
index df42bca..0000000
--- a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/deployment/BaSyxDeployment.java
+++ /dev/null
@@ -1,140 +0,0 @@
-package org.eclipse.basyx.examples.deployment;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.eclipse.basyx.vab.protocol.http.server.AASHTTPServer;
-import org.eclipse.basyx.vab.protocol.http.server.BaSyxContext;
-import org.eclipse.basyx.vab.service.api.BaSyxService;
-import org.junit.rules.ExternalResource;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-
-
-
-/**
- * This class represents a BaSyx deployment with servers / servlets and assets for running BaSyx examples
- * 
- * @author kuhn
- *
- */
-public class BaSyxDeployment extends ExternalResource {
-	
-	/**
-	 * Initiates a logger using the current class
-	 */
-	private static final Logger logger = LoggerFactory.getLogger(BaSyxDeployment.class);
-
-	
-	/**
-	 * Store context objects
-	 */
-	protected Object[] contextComponents = null;
-	
-	/**
-	 * Map runnable names to runnables
-	 */
-	protected Map<String, BaSyxService> contectRunnablesByName = new HashMap<>();
-	
-	/**
-	 * Deployment on HTTP server
-	 */
-	private AASHTTPServer server;
-	
-	
-	
-	/**
-	 * Constructor - accept parameter of type BaSyxContext or Runnable
-	 */
-	public BaSyxDeployment(Object... components) {
-		// Store context objects
-		contextComponents = components;
-		
-		// Store runnable objects by name
-		for (Object obj: contextComponents) {
-			// Check component type
-			if (!(obj instanceof BaSyxService)) continue;
-			
-			// Add BaSyxContextRunnable to context
-			// - Cast object
-			BaSyxService contextRunnable = (BaSyxService) obj;
-			// - Add context runnable to map if it is named
-			if (contextRunnable.getName() == null) continue;
-			// - Add context runnable to map
-			contectRunnablesByName.put(contextRunnable.getName(), contextRunnable);
-		}
-	}
-	
-	
-	
-    /**
-     * Execute before a test case starts
-     */
-    @Override
-	protected void before() {
-    	// Iterate context components
-    	for (Object contextComponent: contextComponents) {
-    		// Process BaSyx context objects that run in a tomcat server
-    		if (contextComponent instanceof BaSyxContext) {
-    			// Get HTTP server resource
-				server = new AASHTTPServer((BaSyxContext) contextComponent);
-				// - Start the server
-				server.start();
-    			// - Continue loop
-    			continue;
-    		}
-    		
-    		// Process runnables
-    		if (contextComponent instanceof BaSyxService) {
-    			// Execute runnable
-    			((BaSyxService) contextComponent).start();
-    			// - Continue loop
-    			continue;
-    		}
-    		
-    		logger.error("Error:"+contextComponent);
-    		
-    		// Unknown deployment context
-    		throw new UnknownContextComponentTypeException();
-    	}
-    }
-
-    
-    /**
-     * Execute after test case ends
-     */
-    @Override
-	protected void after() {
-    	// Iterate context components
-    	for (Object contextComponent: contextComponents) {
-    		// Process BaSyx context objects that run in a tomcat server
-    		if (contextComponent instanceof BaSyxContext) {
-				// - Shutdown the server
-				server.shutdown();
-    			// - Continue loop
-    			continue;
-    		}
-    		
-    		// Process runnables
-    		if (contextComponent instanceof BaSyxService) {
-    			// Execute runnable
-    			((BaSyxService) contextComponent).stop();
-    			// - Continue loop
-    			continue;
-    		}
-    		
-    		// Unknown deployment context
-    		throw new UnknownContextComponentTypeException();
-    	}
-    }
-    
-    
-    /**
-     * Get context runnable by name
-     */
-    public BaSyxService getRunnable(String name) {
-    	return contectRunnablesByName.get(name);
-    }
-}
-
diff --git a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/deployment/UnknownContextComponentTypeException.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/deployment/UnknownContextComponentTypeException.java
deleted file mode 100644
index d2da851..0000000
--- a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/deployment/UnknownContextComponentTypeException.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package org.eclipse.basyx.examples.deployment;
-
-
-/**
- * This exception indicates the presence of an unknown component type in a BaSyx context
- * 
- * @author kuhn
- *
- */
-public class UnknownContextComponentTypeException extends RuntimeException {
-
-	
-	/**
-	 * Version information for serialized instances
-	 */
-	private static final long serialVersionUID = 1L;
-}
diff --git a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/examplescenario/BaSyxExampleScenario.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/examplescenario/BaSyxExampleScenario.java
deleted file mode 100644
index d9542bc..0000000
--- a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/examplescenario/BaSyxExampleScenario.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package org.eclipse.basyx.examples.examplescenario;
-
-import java.util.function.Supplier;
-
-
-
-/**
- * Base class for all BaSyx examples
- * 
- * @author kuhn
- */
-public class BaSyxExampleScenario {
-
-	
-	
-	/**
-	 * Wait for a condition
-	 */
-	protected void waitfor(Supplier<Boolean> function) {
-		while (!function.get()) Thread.yield();
-	}
-}
diff --git a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/scenarios/cloudedgedeployment/CloudEdgeDeploymentScenario.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/scenarios/cloudedgedeployment/CloudEdgeDeploymentScenario.java
index fc6ba2e..0134160 100644
--- a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/scenarios/cloudedgedeployment/CloudEdgeDeploymentScenario.java
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/scenarios/cloudedgedeployment/CloudEdgeDeploymentScenario.java
@@ -1,13 +1,33 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.examples.scenarios.cloudedgedeployment;
 
-import org.basyx.components.AASServer.AASServerComponent;
+
+import java.util.ArrayList;
+import java.util.List;
+
 import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
-import org.eclipse.basyx.aas.registration.api.IAASRegistryService;
-import org.eclipse.basyx.aas.registration.memory.InMemoryRegistry;
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
+import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
+import org.eclipse.basyx.components.IComponent;
+import org.eclipse.basyx.components.aas.AASServerComponent;
+import org.eclipse.basyx.components.aas.configuration.AASServerBackend;
+import org.eclipse.basyx.components.aas.configuration.BaSyxAASServerConfiguration;
+import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
+import org.eclipse.basyx.components.registry.RegistryComponent;
+import org.eclipse.basyx.components.registry.configuration.BaSyxRegistryConfiguration;
+import org.eclipse.basyx.components.registry.configuration.RegistryBackend;
 import org.eclipse.basyx.components.servlet.submodel.SubmodelServlet;
 import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
-import org.eclipse.basyx.vab.protocol.http.server.AASHTTPServer;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.vab.protocol.http.server.BaSyxHTTPServer;
 import org.eclipse.basyx.vab.protocol.http.server.BaSyxContext;
 
 
@@ -20,7 +40,7 @@
  * Server B is created as a server hosted near a machine.
  * It provides a Submodel containing sensor value.
  * 
- * @author conradi
+ * @author conradi, schnicke
  *
  */
 public class CloudEdgeDeploymentScenario {
@@ -28,7 +48,8 @@
 	/**
 	 * The registry used in the manager
 	 */
-	public IAASRegistryService registry;
+	private IAASRegistry registry;
+	public static String registryPath = "http://localhost:8080/registry";
 	
 	/**
 	 * AASManager used to handle registration and server communication
@@ -38,19 +59,23 @@
 	/**
 	 * Identifier of the AAS hosted in the cloud.
 	 */
-	public IIdentifier aasIdentifier = ComponentBuilder.getAAS().getIdentification();
+	public static IIdentifier aasIdentifier = ComponentBuilder.getAAS().getIdentification();
 
 	/**
 	 * Identifier of the SM hosted in the cloud.
 	 * It contains never changing properties of the machine.
 	 */
-	public IIdentifier docuSmIdentifier = ComponentBuilder.getDocuSMDescriptor().getIdentifier();
+	public static IIdentifier docuSmIdentifier = ComponentBuilder.getDocuSMDescriptor().getIdentifier();
 
 	/**
 	 * Identifier of the SM hosted near the machine.
 	 * It contains constantly changing sensor data.
 	 */
-	public IIdentifier edgeSmIdentifier = ComponentBuilder.getEdgeSubmodelDescriptor().getIdentifier();
+	public static IIdentifier edgeSmIdentifier = ComponentBuilder.getEdgeSubmodelDescriptor().getIdentifier();
+
+	// Used for shutting down the scenario
+	private List<IComponent> startedComponents = new ArrayList<>();
+	private BaSyxHTTPServer edgeServer;
 
 	/**
 	 * Main method to start the scenario
@@ -66,28 +91,29 @@
 	 */
 	public CloudEdgeDeploymentScenario() {
 		
-		startupEdgeServer();
-		startupCloudServer();
-		
+		startupRegistryServer();
 		
 		// Create a InMemoryRegistry to be used by the manager
-		registry = new InMemoryRegistry();
+		registry = new AASRegistryProxy(registryPath);
 		
+		startupEdgeServer();
+		startupCloudServer();
+
 		// Create a ConnectedAASManager with the registry created above
 		aasManager = new ConnectedAssetAdministrationShellManager(registry);
 		
 		
 		// Push the AAS to the cloud server
 		// The manager automatically registers it in the registry
-		aasManager.createAAS(ComponentBuilder.getAAS(), aasIdentifier, "http://localhost:8081/cloud");
+		aasManager.createAAS(ComponentBuilder.getAAS(), "http://localhost:8081/cloud");
 		
 		
 		// Get the docuSubmodel from the ComponentBuilder
-		SubModel docuSubmodel = ComponentBuilder.getDocuSM();
+		Submodel docuSubmodel = ComponentBuilder.getDocuSM();
 		
 		// Push the docuSubmodel to the cloud
 		// The manager automatically registers it in the registry
-		aasManager.createSubModel(aasIdentifier, docuSubmodel);
+		aasManager.createSubmodel(aasIdentifier, docuSubmodel);
 		
 
 		// Add the already existing edgeSM to the descriptor of the aas
@@ -95,7 +121,20 @@
 	}
 	
 	/**
-	 * Startup a server responsible for hosting the "current_temp" edgeSubModel
+	 * Startup an empty registry at "http://localhost:8080/registry"
+	 * 
+	 */
+	private void startupRegistryServer() {
+		// Start an InMemory registry server with a direct configuration
+		BaSyxContextConfiguration contextConfig = new BaSyxContextConfiguration(8080, "registry");
+		BaSyxRegistryConfiguration registryConfig = new BaSyxRegistryConfiguration(RegistryBackend.INMEMORY);
+		IComponent component = new RegistryComponent(contextConfig, registryConfig);
+		component.startComponent();
+		startedComponents.add(component);
+	}
+
+	/**
+	 * Startup a server responsible for hosting the "current_temp" edgeSubmodel
 	 * at the endpoint "http://localhost:8082/oven/current_temp"
 	 * 
 	 * In this example this server is hosted close to the machine
@@ -104,21 +143,22 @@
 	 */
 	private void startupEdgeServer() {
 		
-		// Create a BaSyxConetxt for port 8082 with an empty endpoint and the tmpdir for storing its data
-		BaSyxContext context = new BaSyxContext("", System.getProperty("java.io.tmpdir"), "localhost", 8082);
+		// Create a BaSyxConetxt for port 8082 with an empty endpoint
+		BaSyxContextConfiguration contextConfig = new BaSyxContextConfiguration(8082, "");
+		BaSyxContext context = contextConfig.createBaSyxContext();
 		
 		// Get the edgeSubmodel from the ComponentBuilder
-		SubModel edgeSubmodel = ComponentBuilder.createEdgeSubModel();
+		Submodel edgeSubmodel = ComponentBuilder.createEdgeSubmodel();
 		
 		// Create a new SubmodelServlet containing the edgeSubmodel
 		SubmodelServlet smServlet = new SubmodelServlet(edgeSubmodel);
 		
-		// Add the SubmodelServlet mapping to the context at the path "/oven/current_temp"
-		context.addServletMapping("/oven/current_temp/*", smServlet);
+		// Add the SubmodelServlet mapping to the context at the path "/oven/curr_temp"
+		context.addServletMapping("/oven/" + ComponentBuilder.EDGESM_ID_SHORT + "/*", smServlet);
 		
 		
 		// Create and start a HTTP server with the context created above
-		AASHTTPServer edgeServer = new AASHTTPServer(context);
+		edgeServer = new BaSyxHTTPServer(context);
 		edgeServer.start();
 	}
 	
@@ -130,12 +170,24 @@
 	 * 
 	 */
 	private void startupCloudServer() {
-		
-		// Create a server at port 8081 with the endpoint "/cloud"
-		AASServerComponent cloudServer = new AASServerComponent("localhost", 8081, "/cloud", "/");
+		// Load the server context from a .properties file resource
+		BaSyxContextConfiguration contextConfig = new BaSyxContextConfiguration();
+		contextConfig.loadFromResource("CloudEdgeDeploymentScenarioAASContext.properties");
+
+		// Create the AAS - Can alternatively also be loaded from a .property file
+		BaSyxAASServerConfiguration aasServerConfig = new BaSyxAASServerConfiguration(AASServerBackend.INMEMORY, "", registryPath);
+
+		// Create a server according to this configuration
+		AASServerComponent cloudServer = new AASServerComponent(contextConfig, aasServerConfig);
 		
 		// Start the created server
 		cloudServer.startComponent();
+		startedComponents.add(cloudServer);
 	}
 
-}
\ No newline at end of file
+	public void stop() {
+		startedComponents.stream().forEach(IComponent::stopComponent);
+		edgeServer.shutdown();
+	}
+
+}
diff --git a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/scenarios/cloudedgedeployment/ComponentBuilder.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/scenarios/cloudedgedeployment/ComponentBuilder.java
index ffa8803..853ef18 100644
--- a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/scenarios/cloudedgedeployment/ComponentBuilder.java
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/scenarios/cloudedgedeployment/ComponentBuilder.java
@@ -1,9 +1,21 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.examples.scenarios.cloudedgedeployment;
 
+import org.eclipse.basyx.aas.metamodel.api.parts.asset.AssetKind;
 import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.CustomId;
 import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
+import org.eclipse.basyx.aas.metamodel.map.parts.Asset;
 import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
 import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
 
@@ -14,21 +26,17 @@
  *
  */
 public class ComponentBuilder {
+	public static final String AAS_ID_SHORT = "oven";
+	public static final String AAS_ID = "basyx.examples.oven";
+	public static final String AAS_ENDPOINT = "http://localhost:8081/cloud/shells/" + AAS_ID + "/aas";
 
 	public static final String EDGESM_ID_SHORT = "curr_temp";
-	public static final String EDGESM_ID = "current_oven_temperature";
-	public static final String EDGESM_ENDPOINT = "http://localhost:8082/oven/current_temp";
+	public static final String EDGESM_ID = "basyx.examples.oven.current_oven_temperature";
+	public static final String EDGESM_ENDPOINT = "http://localhost:8082/oven/" + EDGESM_ID_SHORT + "/submodel";
 	
 	public static final String DOCUSM_ID_SHORT = "oven_doc";
-	public static final String DOCUSM_ID = "oven_documentation_sm";
-	public static final String DOCUSM_ENDPOINT = "http://localhost:8081/cloud/aasList/aasId/aas/submodels/oven_doc";
-	
-	public static final String AAS_ID_SHORT = "aasIdShort";
-	public static final String AAS_ID = "aasId";
-	public static final String AAS_ENDPOINT = "http://localhost:8081/cloud/aasList/aasId/aas";
-	
-	
-	
+	public static final String DOCUSM_ID = "basyx.examples.oven.oven_documentation_sm";
+	public static final String DOCUSM_ENDPOINT = "http://localhost:8081/cloud/shells/" + AAS_ID + "/aas/submodels/" + DOCUSM_ID_SHORT + "/submodel";
 	
 	/**
 	 * Creates the AAS, which gets pushed to the cloud server
@@ -36,10 +44,13 @@
 	 * @return the created AAS
 	 */
 	public static AssetAdministrationShell getAAS() {
-		AssetAdministrationShell aas = new AssetAdministrationShell();
-		aas.setIdShort(AAS_ID_SHORT);
-		aas.setIdentification(IdentifierType.CUSTOM, AAS_ID);
-		return aas;
+		// Create the oven asset
+		Asset ovenAsset = new Asset("OvenAsset", new CustomId("basyx.examples.OvenAsset"), AssetKind.INSTANCE);
+
+		// Create the AAS representing the oven
+		AssetAdministrationShell ovenAAS = new AssetAdministrationShell(AAS_ID_SHORT, new CustomId(AAS_ID), ovenAsset);
+
+		return ovenAAS;
 	}
 	
 	/**
@@ -48,16 +59,15 @@
 	 * 
 	 * @return the created Submodel
 	 */
-	public static SubModel getDocuSM() {
-		SubModel sm = new SubModel();
-		sm.setIdentification(IdentifierType.CUSTOM, DOCUSM_ID);
-		sm.setIdShort(DOCUSM_ID_SHORT);
+	public static Submodel getDocuSM() {
+		// Create the documentation Submodel
+		Submodel docuSm = new Submodel(DOCUSM_ID_SHORT, new CustomId(DOCUSM_ID));
 
-		Property property = new Property(1000);
-		property.setIdShort("max_temp");
-		sm.addSubModelElement(property);
+		// Create the maximum temperature property and include it in the submodel
+		Property maxTemp = new Property("max_temp", 1000);
+		docuSm.addSubmodelElement(maxTemp);
 		
-		return sm;
+		return docuSm;
 	}
 	
 	/**
@@ -75,17 +85,15 @@
 	 * 
 	 * @return the created Submodel
 	 */
-	public static SubModel createEdgeSubModel() {
-		SubModel sm = new SubModel();
-		sm.setIdentification(IdentifierType.CUSTOM, EDGESM_ID);
-		sm.setIdShort(EDGESM_ID_SHORT);
+	public static Submodel createEdgeSubmodel() {
+		// Create the edge submodel
+		Submodel edgeSm = new Submodel(EDGESM_ID_SHORT, new CustomId(EDGESM_ID));
 		
 		// The property in this Submodel contains the currently measured temperature of the oven
 		// It is represented by a static value in this example
-		Property property = new Property(31);
-		property.setIdShort("temp");
-		sm.addSubModelElement(property);
-		return sm;
+		Property property = new Property("temp", 31);
+		edgeSm.addSubmodelElement(property);
+		return edgeSm;
 	}
 	
 	/**
diff --git a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/scenarios/staticdynamic/ExampleDynamicSubmodel.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/scenarios/staticdynamic/ExampleDynamicSubmodel.java
new file mode 100644
index 0000000..da55cbb
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/scenarios/staticdynamic/ExampleDynamicSubmodel.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.scenarios.staticdynamic;
+
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+
+/**
+ * Minimal implementation of a dynamic information Submodel <br>
+ * Please note that it is just for showcasing, several mandatory attributes are
+ * missing.
+ * 
+ * @author schnicke, conradi
+ *
+ */
+public class ExampleDynamicSubmodel extends Submodel {
+
+	public static final String SM_ID_SHORT = "maintenance";
+	public static final String SM_ID = "maintenanceInformationSubmodel";
+
+	public static final String PROPERTY_ID_SHORT = "interval";
+	public static final String PROPERTY_VALUE = "2 months";
+	
+	
+	public ExampleDynamicSubmodel() {
+		// Create Property
+		Property interval = new Property();
+		interval.setValue(PROPERTY_VALUE);
+		interval.setIdShort(PROPERTY_ID_SHORT);
+
+		// Add the property to the submodel
+		addSubmodelElement(interval);
+
+		// Set the idShort
+		setIdShort(SM_ID_SHORT);
+		
+		// Set Identification
+		setIdentification(IdentifierType.CUSTOM, SM_ID);
+	}
+}
diff --git a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/scenarios/staticdynamic/StaticDynamicScenario.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/scenarios/staticdynamic/StaticDynamicScenario.java
new file mode 100644
index 0000000..86630e8
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/scenarios/staticdynamic/StaticDynamicScenario.java
@@ -0,0 +1,139 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.scenarios.staticdynamic;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
+import org.eclipse.basyx.aas.aggregator.proxy.AASAggregatorProxy;
+import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
+import org.eclipse.basyx.components.IComponent;
+import org.eclipse.basyx.components.aas.AASServerComponent;
+import org.eclipse.basyx.components.aas.aasx.AASXPackageManager;
+import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
+import org.eclipse.basyx.components.registry.RegistryComponent;
+import org.eclipse.basyx.components.registry.configuration.BaSyxRegistryConfiguration;
+import org.eclipse.basyx.components.registry.configuration.RegistryBackend;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.support.bundle.AASBundle;
+import org.eclipse.basyx.support.bundle.AASBundleHelper;
+import org.xml.sax.SAXException;
+
+/**
+ * Example scenario showcasing how to enrich AAS data provided as AASX with static data <br>
+ * For this, a previously defined AASX package is loaded and a static
+ * submodel is added to the already defined submodels <br>
+ * For a detailed description of the scenario, see:<br>
+ * https://wiki.eclipse.org/BaSyx_/_Scenarios_/_Static_Dynamic_Extension 
+ * 
+ * @author schnicke, conradi
+ *
+ */
+public class StaticDynamicScenario {
+	
+	public static final String REGISTRY_URL = "http://localhost:4000/registry";
+	public static final String SERVER_URL = "http://localhost:4001/aasx/shells";
+
+	public static final String AAS_ID = "smart.festo.com/demo/aas/1/1/454576463545648365874"; 
+	public static final String AAS_ID_SHORT = "Festo_3S7PM0CP4BD";
+	public static final String AAS_ENDPOINT = SERVER_URL + "shells/smart.festo.com%2Fdemo%2Faas%2F1%2F1%2F454576463545648365874/aas";
+	
+	private List<IComponent> startedComponents = new ArrayList<>();
+	
+	
+	
+	public static void main(String[] args) throws InvalidFormatException, IOException, ParserConfigurationException, SAXException {
+		new StaticDynamicScenario();
+	}
+
+	public StaticDynamicScenario() throws InvalidFormatException, IOException, ParserConfigurationException, SAXException {
+		
+		// Startup the registry server
+		startRegistry();
+		
+		// Startup the server
+		startAASServer();
+		
+		// Load Bundles from .aasx file
+		AASXPackageManager packageManager = new AASXPackageManager("aasx/01_Festo.aasx");
+		Set<AASBundle> bundles = packageManager.retrieveAASBundles();
+		
+		// Create static Submodel
+		Submodel sm = new ExampleDynamicSubmodel();
+
+		// Get the correct Bundle from the Set
+		AASBundle bundle = findBundle(bundles, AAS_ID_SHORT);
+		
+		// Add the new Submodel to the Bundle
+		bundle.getSubmodels().add(sm);
+		
+		// Load the new Bundles to the Server
+		AASBundleHelper.integrate(new AASAggregatorProxy(SERVER_URL), bundles);
+		
+		// Get a RegistryProxy and register all Objects contained in the Bundles
+		AASRegistryProxy proxy = new AASRegistryProxy(REGISTRY_URL);
+		AASBundleHelper.register(proxy, bundles, SERVER_URL);
+				
+	}
+	
+	/**
+	 * Starts an empty registry at "http://localhost:4000"
+	 */
+	private void startRegistry() {
+		// Load a registry context configuration using a .properties file
+		BaSyxContextConfiguration contextConfig = new BaSyxContextConfiguration();
+		contextConfig.loadFromResource("RegistryContext.properties");
+		BaSyxRegistryConfiguration registryConfig = new BaSyxRegistryConfiguration(RegistryBackend.INMEMORY);
+		RegistryComponent registry = new RegistryComponent(contextConfig, registryConfig);
+		registry.startComponent();
+		startedComponents.add(registry);
+	}
+
+	/**
+	 * Startup an empty server at "http://localhost:4001/aasx/"
+	 */	
+	private void startAASServer() {
+		// Create a server at port 4001 with the endpoint "/aasx"
+		BaSyxContextConfiguration contextConfig = new BaSyxContextConfiguration(4001, "/aasx");
+		AASServerComponent aasServer = new AASServerComponent(contextConfig);
+		
+		// Start the created server
+		aasServer.startComponent();
+		startedComponents.add(aasServer);
+	}
+	
+	
+	/**
+	 * Finds the Bundle containing the AAS with the specified IdShort
+	 * 
+	 * @param bundles the Set of Bundles
+	 * @param aasID the Id of the AAS of the wanted Bundle
+	 * @return the Bundle containing the AAS with the specified Id or null if it does not exist
+	 */
+	private AASBundle findBundle(Set<AASBundle> bundles, String aasIdShort) {
+		for (AASBundle aasBundle : bundles) {
+			if(aasBundle.getAAS().getIdShort().equals(aasIdShort))
+				return aasBundle;
+		}
+		return null;
+	}
+	
+	/**
+	 * Shuts down all started IComponent servers
+	 */
+	public void stop() {
+		startedComponents.stream().forEach(IComponent::stopComponent);
+	}
+}
diff --git a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/aas/AddSubmodelToAAS.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/aas/AddSubmodelToAAS.java
new file mode 100644
index 0000000..088cea1
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/aas/AddSubmodelToAAS.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.aas;
+
+import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+
+/**
+ * This snippet showcases how to add a Submodel to an AAS,
+ * that already exists on a server
+ * 
+ * @author conradi
+ *
+ */
+public class AddSubmodelToAAS {
+
+	/**
+	 * Adds a Submodel to an AAS
+	 * 
+	 * @param submodel the Submodel to be added
+	 * @param aas the AAS the Submodel should be added to
+	 */
+	public static void addSubmodelToAAS(Submodel submodel, IAssetAdministrationShell aas) {
+		
+		// Add the submodel to the AAS
+		// If the given AAS is a ConnectedAssetAdministrationShell
+		// the Submodel will be uploaded to the server the AAS is hosted on
+		// The Submodel will NOT be registered. The RegisterSubmodel snippet can be used for that.
+		aas.addSubmodel(submodel);
+	}
+	
+}
diff --git a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/aas/CreateAAS.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/aas/CreateAAS.java
new file mode 100644
index 0000000..0ca30e7
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/aas/CreateAAS.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.aas;
+
+import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.map.parts.Asset;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+
+/**
+ * Snippet that showcases how to create an AssetAdministrationShell
+ * with only the mandatory attributes.
+ * 
+ * @author conradi
+ *
+ */
+public class CreateAAS {
+
+	/**
+	 * Creates a new AAS
+	 * 
+	 * @param idShort the idShort of the AAS to be created
+	 * @param aasIdentifier the Identifier of the AAS to be created
+	 * @param asset the asset to be contained in the new AAS
+	 * @return the newly created AAS
+	 */
+	public static AssetAdministrationShell createAAS(String idShort, IIdentifier aasIdentifier, Asset asset) {
+		
+		// Create a new AssetAdministrationShell object
+		AssetAdministrationShell aas = new AssetAdministrationShell(idShort, aasIdentifier, asset);
+		return aas;
+	}
+	
+}
diff --git a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/aas/DeleteSubmodelFromAAS.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/aas/DeleteSubmodelFromAAS.java
new file mode 100644
index 0000000..8fcae73
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/aas/DeleteSubmodelFromAAS.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.aas;
+
+import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+
+/**
+ * Snippet that showcases how to delete a Submodel from a server
+ * 
+ * @author conradi
+ *
+ */
+public class DeleteSubmodelFromAAS {
+
+	/**
+	 * Removes a Submodel from an AAS
+	 * 
+	 * @param smIdentifier the Identifier of the Submodel to be deleted
+	 * @param aas the AAS the Submodel belongs to
+	 */
+	public static void deleteSubmodelFromAAS(IIdentifier smIdentifier, IAssetAdministrationShell aas) {
+		
+		// Delete the Submodel from the AAS
+		// Does NOT deregisters the Submodel
+		// The DeregisterSubmodel snippet can be used to do that
+		aas.removeSubmodel(smIdentifier);
+	}
+}
diff --git a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/aas/RetrieveSubmodelFromAAS.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/aas/RetrieveSubmodelFromAAS.java
new file mode 100644
index 0000000..0b52ffc
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/aas/RetrieveSubmodelFromAAS.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.aas;
+
+import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+
+
+/**
+ * This snippet showcases how to retrieve a Submodel from an AAS
+ * 
+ * @author conradi
+ *
+ */
+public class RetrieveSubmodelFromAAS {
+
+	/**
+	 * Gets a Submodel from an AAS
+	 * 
+	 * @param smIdentifier the Identifier of the requested Submodel
+	 * @return the requested Submodel
+	 */
+	public static ISubmodel retrieveSubmodelFromAAS(IIdentifier smIdentifier, IAssetAdministrationShell aas) {
+		// Get the requested Submodel from the AAS
+		ISubmodel submodel = aas.getSubmodel(smIdentifier);
+		return submodel;
+	}
+	
+}
diff --git a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/manager/AddSubmodelToAAS.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/manager/AddSubmodelToAAS.java
new file mode 100644
index 0000000..8000344
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/manager/AddSubmodelToAAS.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.manager;
+
+import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
+import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+
+/**
+ * This snippet showcases how to add a Submodel to an AAS,
+ * that already exists on a server.
+ * It uses the AASManager
+ * 
+ * @author conradi
+ *
+ */
+public class AddSubmodelToAAS {
+
+	/**
+	 * Adds a Submodel to an AAS and registers it
+	 * 
+	 * @param submodel the Submodel to be added
+	 * @param aasIdentifier the Identifier of the AAS the Submodel should be added to
+	 * @param registryServerURL the URL of the registry server
+	 */
+	public static void addSubmodelToAAS(Submodel submodel, IIdentifier aasIdentifier, String registryServerURL) {
+
+		// Create a proxy pointing to the registry server
+		AASRegistryProxy registryProxy = new AASRegistryProxy(registryServerURL);
+		
+		// Create a ConnectedAASManager using the registryProxy as its registry
+		ConnectedAssetAdministrationShellManager manager =
+				new ConnectedAssetAdministrationShellManager(registryProxy);
+		
+		// Add the submodel to the AAS using the ConnectedAASManager
+		// The manager pushes the submodel to the server and registers it
+		// For this to work, the Identification of the Submodel has to be set
+		manager.createSubmodel(aasIdentifier, submodel);
+		
+	}
+	
+}
diff --git a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/manager/DeleteAAS.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/manager/DeleteAAS.java
new file mode 100644
index 0000000..228a3bf
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/manager/DeleteAAS.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.manager;
+
+import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
+import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+
+/**
+ * Snippet that showcases how to delete an AAS from a server using the AASManager
+ * 
+ * @author conradi
+ *
+ */
+public class DeleteAAS {
+
+	/**
+	 * Removes an AAS from the server
+	 * 
+	 * @param aasIdentifier the Identifier of the AAS to be deleted
+	 * @param registryServerURL the URL of the registry server (e.g. http://localhost:8080/registry)
+	 */
+	public static void deleteAAS(IIdentifier aasIdentifier, String registryServerURL) {
+	
+		// Create a proxy pointing to the registry server
+		AASRegistryProxy registryProxy = new AASRegistryProxy(registryServerURL);
+		
+		// Create a ConnectedAASManager using the registryProxy as its registry
+		ConnectedAssetAdministrationShellManager manager =
+				new ConnectedAssetAdministrationShellManager(registryProxy);
+		
+		// Delete the AAS
+		// Automatically deregisters it
+		manager.deleteAAS(aasIdentifier);
+	}
+}
diff --git a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/manager/DeleteSubmodelFromAAS.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/manager/DeleteSubmodelFromAAS.java
new file mode 100644
index 0000000..10e9f67
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/manager/DeleteSubmodelFromAAS.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.manager;
+
+import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
+import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+
+/**
+ * Snippet that showcases how to delete a Submodel from a server using the AASManager
+ * 
+ * @author conradi
+ *
+ */
+public class DeleteSubmodelFromAAS {
+
+	/**
+	 * Removes a Submodel from an AAS
+	 * 
+	 * @param smIdentifier the Identifier of the Submodel to be deleted
+	 * @param aasIdentifier the Identifier of the AAS the Submodel belongs to
+	 * @param registryServerURL the URL of the registry server (e.g. http://localhost:8080/registry)
+	 */
+	public static void deleteSubmodelFromAAS(IIdentifier smIdentifier, IIdentifier aasIdentifier, String registryServerURL) {
+	
+		// Create a proxy pointing to the registry server
+		AASRegistryProxy registryProxy = new AASRegistryProxy(registryServerURL);
+		
+		// Create a ConnectedAASManager using the registryProxy as its registry
+		ConnectedAssetAdministrationShellManager manager =
+				new ConnectedAssetAdministrationShellManager(registryProxy);
+		
+		// Delete the Submodel
+		// Automatically deregisters it
+		manager.deleteSubmodel(aasIdentifier, smIdentifier);
+	}
+}
diff --git a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/manager/PushAASToServer.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/manager/PushAASToServer.java
new file mode 100644
index 0000000..e821194
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/manager/PushAASToServer.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.manager;
+
+import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
+import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
+
+
+/**
+ * This snippet showcases how to push an AAS to a server using the AASManager
+ * 
+ * @author conradi
+ *
+ */
+public class PushAASToServer {
+	
+	/**
+	 * Pushes the AAS to a server and registers it
+	 * 
+	 * @param aas the AssetAdministrationShell to be pushed to the server
+	 * @param aasServerURL the URL of the aas server (e.g. http://localhost:8080/aasComponent)
+	 * @param registryServerURL the URL of the registry server (e.g. http://localhost:8080/registry)
+	 */
+	public static void pushAAS(AssetAdministrationShell aas, String aasServerURL, String registryServerURL) {
+
+		// Create a proxy pointing to the registry server
+		AASRegistryProxy registryProxy = new AASRegistryProxy(registryServerURL);
+		
+		// Create a ConnectedAASManager using the registryProxy as its registry
+		ConnectedAssetAdministrationShellManager manager =
+				new ConnectedAssetAdministrationShellManager(registryProxy);
+		
+		// The ConnectedAASManager automatically pushes the given AAS
+		// to the server to which the address was given
+		// It also registers the AAS in the registry it got in its ctor
+		manager.createAAS(aas, aasServerURL);
+	}
+}
diff --git a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/manager/RetrieveAAS.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/manager/RetrieveAAS.java
new file mode 100644
index 0000000..9f2f6f2
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/manager/RetrieveAAS.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.manager;
+
+import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
+import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
+import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+
+/**
+ * This snippet showcases how to retrieve an AAS from a server using the AASManager
+ * 
+ * @author conradi
+ *
+ */
+public class RetrieveAAS {
+
+	/**
+	 * Get an AAS from a server
+	 * 
+	 * @param aasIdentifier the Identifier of the requested AAS
+	 * @param registryServerURL the URL of the registry server
+	 * @return The requested AAS as ConnectedAAS
+	 */
+	public static IAssetAdministrationShell retrieveRemoteAAS(IIdentifier aasIdentifier, String registryServerURL) {
+
+		// Create a proxy pointing to the registry server
+		AASRegistryProxy registryProxy = new AASRegistryProxy(registryServerURL);
+		
+		// Create a ConnectedAASManager using the registryProxy as its registry
+		ConnectedAssetAdministrationShellManager manager =
+				new ConnectedAssetAdministrationShellManager(registryProxy);
+		
+		// Get the requested AAS from the manager
+		return manager.retrieveAAS(aasIdentifier);
+	}
+	
+}
diff --git a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/manager/RetrieveSubmodelFromAAS.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/manager/RetrieveSubmodelFromAAS.java
new file mode 100644
index 0000000..0d05a55
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/manager/RetrieveSubmodelFromAAS.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.manager;
+
+import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
+import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+
+
+/**
+ * This snippet showcases how to retrieve a Submodel
+ * from an AAS on a server using the AASManager
+ * 
+ * @author conradi
+ *
+ */
+public class RetrieveSubmodelFromAAS {
+
+	/**
+	 * Gets a Submodel from an AAS
+	 * 
+	 * @param smIdentifier the Identifier of the requested Submodel
+	 * @param aasIdentifier the Identifier of the AAS the Submodel belongs to
+	 * @param registryServerURL the URL of the registry server
+	 * @return the requested Submodel as ConnectedSubmodel
+	 */
+	public static ISubmodel retrieveSubmodelFromAAS(IIdentifier smIdentifier, IIdentifier aasIdentifier, String registryServerURL) {
+
+		// Create a proxy pointing to the registry server
+		AASRegistryProxy registryProxy = new AASRegistryProxy(registryServerURL);
+		
+		// Create a ConnectedAASManager using the registryProxy as its registry
+		ConnectedAssetAdministrationShellManager manager =
+				new ConnectedAssetAdministrationShellManager(registryProxy);
+		
+		// Get the requested Submodel from the ConnectedAASManager using the Identifiers of the AAS and the SM
+		return manager.retrieveSubmodel(aasIdentifier, smIdentifier);
+	}
+	
+}
diff --git a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/property/CreateLambdaProperty.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/property/CreateLambdaProperty.java
new file mode 100644
index 0000000..029838e
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/property/CreateLambdaProperty.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.property;
+
+import java.util.function.Consumer;
+import java.util.function.Supplier;
+
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.AASLambdaPropertyHelper;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+
+/**
+ * This snippet showcases how create a lambda Property, i.e. a property that
+ * retrieves its value at runtime from an arbitrary backend. <br>
+ * This is for example useful if a sensor or a edge device has to be connected.
+ * It is valid to only provide a getter, i.e. in case of a sensor. <br>
+ * The lambda property will only work if it is included in a submodel and being
+ * hosted} <br>
+ * <br>
+ * Please note, that a submodel containing a dynamic property can not be pushed
+ * to another server. Instead, it has to be hosted on its own server (see
+ * {@link org.eclipse.basyx.examples.snippets.submodel.HostPreconfiguredSubmodel
+ * Host Preconfigured Submodel}).
+ * 
+ * @author schnicke
+ *
+ */
+public class CreateLambdaProperty {
+
+	/**
+	 * Configures the passed property so that calls to its setValue/getValue are
+	 * delegated
+	 * 
+	 * @param propertyIdShort
+	 *            id of the lambda property
+	 * @param type
+	 *            type of the lambda property
+	 * @param get
+	 *            getter to be used
+	 * @param set
+	 *            setter to be used
+	 * @return the created lambda property
+	 */
+	public static Property createLambdaProperty(String propertyIdShort, ValueType type, Supplier<Object> get, Consumer<Object> set) {
+		Property prop = new Property(propertyIdShort, type);
+
+		AASLambdaPropertyHelper.setLambdaValue(prop, get, set);
+
+		return prop;
+	}
+}
diff --git a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/registry/DeregisterAAS.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/registry/DeregisterAAS.java
new file mode 100644
index 0000000..f26d853
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/registry/DeregisterAAS.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.registry;
+
+import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+
+/**
+ * Snippet that showcases how to deregister a AAS from a RegistryComponent
+ * 
+ * @author conradi
+ *
+ */
+public class DeregisterAAS {
+
+	/**
+	 * Deregisters a given AssetAdministrationShell from a registry.
+	 * 
+	 * @param smIdentifier the Identifier of the AAS to be deregistered 
+	 * @param registryServerURL the address of the registry
+	 */
+	public static void registerAAS(IIdentifier aasIdentifier, String registryServerURL) {
+		
+		// Create a proxy pointing to the registry
+		AASRegistryProxy registryProxy = new AASRegistryProxy(registryServerURL);
+		
+		// Delete the AAS from the registry
+		registryProxy.delete(aasIdentifier);
+	}
+	
+}
diff --git a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/registry/DeregisterSubmodel.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/registry/DeregisterSubmodel.java
new file mode 100644
index 0000000..3d03fa8
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/registry/DeregisterSubmodel.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.registry;
+
+import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+
+/**
+ * Snippet that showcases how to deregister a Submodel
+ * 
+ * @author conradi
+ *
+ */
+public class DeregisterSubmodel {
+
+	/**
+	 * Deregisters a Submodel from a registry.
+	 * 
+	 * @param smIdentifier the Identifier of the Submodel to be deregistered 
+	 * @param aasIdentifier the Identifier of the AAS the Submodel belongs to
+	 * @param registryServerURL the address of the registry
+	 */
+	public static void registerSubmodel(IIdentifier smIdentifier, IIdentifier aasIdentifier, String registryServerURL) {
+		
+		// Create a proxy pointing to the registry
+		AASRegistryProxy registryProxy = new AASRegistryProxy(registryServerURL);
+		
+		// Delete the Submodel from the registry
+		registryProxy.delete(aasIdentifier, smIdentifier);
+	}
+
+}
diff --git a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/registry/LookupAAS.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/registry/LookupAAS.java
new file mode 100644
index 0000000..90a38ce
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/registry/LookupAAS.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.registry;
+
+import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
+import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+
+/**
+ * Snippet that showcases how to look up an AAS in a RegistryComponent
+ * 
+ * @author conradi
+ *
+ */
+public class LookupAAS {
+
+	/**
+	 * Gets the Descriptor of the requested AAS from a registry
+	 * 
+	 * @param aasIdentifier the Identifier of the AAS to be looked up in the registry
+	 * @param registryServerURL the URL of the registry server
+	 * @return the AASDescriptor looked up in the registry
+	 */
+	public static AASDescriptor lookupAAS(IIdentifier aasIdentifier, String registryServerURL) {
+		
+		// Create a proxy pointing to the registry
+		AASRegistryProxy registryProxy = new AASRegistryProxy(registryServerURL);
+		
+		// Lookup the AAS in the registry
+		return registryProxy.lookupAAS(aasIdentifier);
+	}
+	
+}
diff --git a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/registry/LookupSubmodel.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/registry/LookupSubmodel.java
new file mode 100644
index 0000000..5e9b554
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/registry/LookupSubmodel.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.registry;
+
+import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
+import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+
+/**
+ * Snippet that showcases how to look up a Submodel in a RegistryComponent
+ * 
+ * @author conradi
+ *
+ */
+public class LookupSubmodel {
+
+	/**
+	 * Gets the Descriptor of the requested Submodel from a registry
+	 * 
+	 * @param smIdentifier the Identifier of the Submodel to be looked up in the registry
+	 * @param aasIdentifier the Identifier of the AAS the Submodel belongs to
+	 * @param registryServerURL the URL of the registry server
+	 * @return the SubmodelDescriptor looked up in the registry
+	 */
+	public static SubmodelDescriptor lookupSubmodel(IIdentifier smIdentifier, IIdentifier aasIdentifier, String registryServerURL) {
+		
+		// Create a proxy pointing to the registry
+		AASRegistryProxy registryProxy = new AASRegistryProxy(registryServerURL);
+		
+		// Lookup the Submodel in the registry
+		return registryProxy.lookupSubmodel(aasIdentifier, smIdentifier);
+	}
+	
+}
diff --git a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/registry/RegisterAAS.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/registry/RegisterAAS.java
new file mode 100644
index 0000000..c0e2bf1
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/registry/RegisterAAS.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.registry;
+
+import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
+import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
+
+/**
+ * Snippet that showcases how to register a given AAS in a RegistryComponent
+ * 
+ * @author conradi
+ *
+ */
+public class RegisterAAS {
+
+	/**
+	 * Registers a given AssetAdministrationShell in a registry.
+	 * 
+	 * @param aas the AssetAdministrationShell to be registered
+	 * @param aasEndpoint the address where the AAS will be hosted (e.g. http://localhost:8080/aasList/{aasId}/aas)
+	 * @param registryServerURL the address of the registry
+	 */
+	public static void registerAAS(IAssetAdministrationShell aas, String aasEndpoint, String registryServerURL) {
+		
+		// Create a proxy pointing to the registry
+		AASRegistryProxy registryProxy = new AASRegistryProxy(registryServerURL);
+		
+		// Create a Descriptor for the AAS using the endpoint where it will be hosted
+		AASDescriptor descriptor = new AASDescriptor(aas, aasEndpoint);
+		
+		// Register this Descriptor in the registry
+		registryProxy.register(descriptor);
+	}
+	
+}
diff --git a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/registry/RegisterSubmodel.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/registry/RegisterSubmodel.java
new file mode 100644
index 0000000..c723772
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/registry/RegisterSubmodel.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.registry;
+
+import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
+import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+
+/**
+ * Snippet that showcases how to register a given Submodel in a RegistryComponent
+ * 
+ * @author conradi
+ *
+ */
+public class RegisterSubmodel {
+
+	/**
+	 * Registers a given Submodel in a registry.
+	 * 
+	 * @param submodel the Submodel to be registered
+	 * @param smEndpoint the address where the SM will be hosted (e.g. http://localhost:8080/aasList/{aasId}/aas/submodels/{smId})
+	 * @param aasIdentifier the Identifier of the AAS the Submodel should be registered to
+	 * @param registryServerURL the address of the registry
+	 */
+	public static void registerSubmodel(ISubmodel submodel, String smEndpoint, IIdentifier aasIdentifier, String registryServerURL) {
+		
+		// Create a proxy pointing to the registry
+		AASRegistryProxy registryProxy = new AASRegistryProxy(registryServerURL);
+		
+		// Create a Descriptor for the sm using the endpoint where it will be hosted
+		SubmodelDescriptor descriptor = new SubmodelDescriptor(submodel, smEndpoint);
+		
+		// Register this Descriptor in the registry
+		registryProxy.register(aasIdentifier, descriptor);
+	}
+
+}
diff --git a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/submodel/AddSubmodelElement.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/submodel/AddSubmodelElement.java
new file mode 100644
index 0000000..ee0fdbb
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/submodel/AddSubmodelElement.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.submodel;
+
+import org.eclipse.basyx.examples.snippets.manager.RetrieveSubmodelFromAAS;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElement;
+
+/**
+ * This snippet showcases how add to a SubmodelElement to a Submodel,
+ * that already exists on a server
+ * 
+ * @author conradi
+ *
+ */
+public class AddSubmodelElement {
+
+	/**
+	 * Adds a SubmodelElement to a remote Submodel
+	 * 
+	 * @param smElement the SubmodelElement to be added
+	 * @param smIdentifier the Identifier of the Submodel the element should be added to
+	 * @param aasIdentifier the Identifier of the AAS the Submodel belongs to
+	 * @param registryServerURL the URL of the registry server
+	 */
+	public static void addSubmodelElement(SubmodelElement smElement, IIdentifier smIdentifier, IIdentifier aasIdentifier, String registryServerURL) {
+
+		// Get the ConnectedSubmodel
+		ISubmodel submodel = RetrieveSubmodelFromAAS.retrieveSubmodelFromAAS(smIdentifier, aasIdentifier, registryServerURL);
+		
+		// Add the element to it
+		submodel.addSubmodelElement(smElement);
+		
+	}
+
+}
diff --git a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/submodel/CreateSubmodel.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/submodel/CreateSubmodel.java
new file mode 100644
index 0000000..c7804cb
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/submodel/CreateSubmodel.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.submodel;
+
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+
+/**
+ * Snippet that showcases how to create a Submodel
+ * with the mandatory attributes and a Property.
+ * 
+ * @author conradi
+ *
+ */
+public class CreateSubmodel {
+
+	/**
+	 * Creates a new Submodel with a Property
+	 * 
+	 * @param idShort the idShort of the Submodel to be created
+	 * @param smIdentifier the Identifier of the Submodel to be created
+	 * @param propertyIdShort the idShort of the Property to be created
+	 * @param propertyValue the value of the Property (see PropertyValueTypeDef for allowed value types)
+	 * @return the newly created Submodel
+	 */
+	public static Submodel createSubmodel(String idShort, IIdentifier smIdentifier, String propertyIdShort, Object propertyValue) {
+		
+		// Create a new Property with the given idShort and value
+		Property property = new Property(propertyIdShort, propertyValue);
+		
+		// Create a new Submodel object
+		Submodel sm = new Submodel(idShort, smIdentifier);
+		
+		// Add the Property to the Submodel
+		sm.addSubmodelElement(property);
+		
+		return sm;
+	}
+	
+}
diff --git a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/submodel/DeleteSubmodelElement.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/submodel/DeleteSubmodelElement.java
new file mode 100644
index 0000000..98e3e1f
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/submodel/DeleteSubmodelElement.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.submodel;
+
+import org.eclipse.basyx.examples.snippets.manager.RetrieveSubmodelFromAAS;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+
+/**
+ * Snippet that showcases how to delete a SubmodelElement from a Submodel
+ * 
+ * @author conradi
+ *
+ */
+public class DeleteSubmodelElement {
+
+	/**
+	 * Removes a SubmodelElement from a Submodel
+	 * 
+	 * @param elementId the Id of the Element to be deleted (can also be a path if the Element is in a Collection)
+	 * @param smIdentifier the Identifier of the Submodel the Element belongs to
+	 * @param aasIdentifier the Identifier of the AAS the Submodel belongs to
+	 * @param registryServerURL the URL of the registry server (e.g. http://localhost:8080/registry)
+	 */
+	public static void deleteSubmodelElement(String elementId, IIdentifier smIdentifier, IIdentifier aasIdentifier, String registryServerURL) {
+	
+		// Retrieve the Submodel from the server as a ConnectedSubmodel
+		ISubmodel submodel = RetrieveSubmodelFromAAS.retrieveSubmodelFromAAS(smIdentifier, aasIdentifier, registryServerURL);
+		
+		// Delete the Element from the Submodel
+		submodel.deleteSubmodelElement(elementId);
+	}
+}
diff --git a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/submodel/ExecuteOperation.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/submodel/ExecuteOperation.java
new file mode 100644
index 0000000..cdaeac8
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/submodel/ExecuteOperation.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.submodel;
+
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperation;
+
+/**
+ * Snippet that showcases how to execute an Operation contained in a Submodel
+ * 
+ * @author conradi
+ *
+ */
+public class ExecuteOperation {
+
+	/**
+	 * Executes an Operation with the given parameters and return the result.
+	 * The execution itself is run on the remote server
+	 * 
+	 * @param operationId the idShort of the Operation to be executed
+	 * @param operationParameters the parameters for the execution
+	 * @param smIdentifier the Identifier of the Submodel the Operation belongs to
+	 * @param aasIdentifier the Identifier of the AAS the Submodel belongs to
+	 * @param registryServerURL the URL of the registry server
+	 * @return the result of the execution
+	 * @throws Exception thrown if the execution of the Operation threw an Exception
+	 */
+	public static Object executeOperation(String operationId, Object[] operationParameters, IIdentifier smIdentifier, IIdentifier aasIdentifier, String registryServerURL) throws Exception {
+
+		// Get the Operation from the Submodel
+		ISubmodelElement element = RetrieveSubmodelElement.retrieveSubmodelElement(operationId, smIdentifier, aasIdentifier, registryServerURL);
+		
+		// Check if the element is really an Operation
+		if( ! (element instanceof IOperation)) {
+			// The element with the given Id is not an Operation
+			throw new IllegalArgumentException("The SubmodelElement '" + operationId + "' is not an Operation");
+		}
+		
+		// Cast the retrieved ISubmodelElement to an IOperation
+		IOperation operation = (IOperation) element;
+		
+		// Invoke the Operation and return the Result
+		return operation.invoke(operationParameters);
+	}
+	
+}
diff --git a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/submodel/HostPreconfiguredSubmodel.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/submodel/HostPreconfiguredSubmodel.java
new file mode 100644
index 0000000..36db60b
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/submodel/HostPreconfiguredSubmodel.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.submodel;
+
+import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
+import org.eclipse.basyx.components.servlet.submodel.SubmodelServlet;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.vab.protocol.http.server.BaSyxHTTPServer;
+import org.eclipse.basyx.vab.protocol.http.server.BaSyxContext;
+
+/**
+ * This snippet showcases how host a submodel on a standalone server, i.e. a
+ * server that is preconfigured with a submodel and does not allow upload of
+ * additional AAS/Submodels<br>
+ * For instance, this can be used by a device manufacturer to provide a submodel
+ * containing live sensor data in combination with a dynamic property (cf.
+ * {@link org.eclipse.basyx.examples.snippets.property.CreateLambdaProperty
+ * CreateDynamicProperty}). <br>
+ * 
+ * @author schnicke
+ *
+ */
+public class HostPreconfiguredSubmodel {
+
+	/**
+	 * Creates, configures and starts an HTTP Server providing a preconfigured
+	 * submodel
+	 * 
+	 * @param serverContext
+	 *            the context configuration of the server
+	 * @param sm
+	 *            the submodel to be hosted
+	 * @return the started server
+	 */
+	public static BaSyxHTTPServer hostPreconfiguredSubmodel(BaSyxContextConfiguration serverContext, Submodel sm) {
+		// Create the BaSyx context from the context configuration
+		BaSyxContext context = serverContext.createBaSyxContext();
+
+		// Create a new SubmodelServlet containing the passed submodel
+		SubmodelServlet smServlet = new SubmodelServlet(sm);
+
+		// Add the SubmodelServlet mapping to the context at the path "$SmIdShort"
+		// Here, it possible to add further submodels using the same pattern
+		context.addServletMapping("/" + sm.getIdShort() + "/*", smServlet);
+
+		// Create and start a HTTP server with the context created above
+		BaSyxHTTPServer preconfiguredSmServer = new BaSyxHTTPServer(context);
+		preconfiguredSmServer.start();
+
+		return preconfiguredSmServer;
+	}
+
+}
diff --git a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/submodel/RetrieveSubmodelElement.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/submodel/RetrieveSubmodelElement.java
new file mode 100644
index 0000000..6893d49
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/submodel/RetrieveSubmodelElement.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.submodel;
+
+import org.eclipse.basyx.examples.snippets.manager.RetrieveSubmodelFromAAS;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+
+/**
+ * This snippet showcases how to retrieve a SubmodelElement from a remote Submodel
+ * 
+ * @author conradi
+ *
+ */
+public class RetrieveSubmodelElement {
+
+	/**
+	 * Gets a SubmodelElement from a remote Submodel
+	 * 
+	 * @param elementId the idShort SubmodelElement to be retrieved
+	 * @param smIdentifier the Identifier of the Submodel the element belongs to
+	 * @param aasIdentifier the Identifier of the AAS the Submodel belongs to
+	 * @param registryServerURL the URL of the registry server
+	 * @return the requested SubmodelElement
+	 */
+	public static ISubmodelElement retrieveSubmodelElement(String elementId, IIdentifier smIdentifier, IIdentifier aasIdentifier, String registryServerURL) {
+
+		// Get the ConnectedSubmodel
+		ISubmodel submodel = RetrieveSubmodelFromAAS.retrieveSubmodelFromAAS(smIdentifier, aasIdentifier, registryServerURL);
+		
+		// Add the element to it
+		return submodel.getSubmodelElement(elementId);
+		
+	}
+}
diff --git a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/support/ExampleAASComponent.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/support/ExampleAASComponent.java
new file mode 100644
index 0000000..242504a
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/support/ExampleAASComponent.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.support;
+
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
+import org.eclipse.basyx.components.aas.AASServerComponent;
+import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
+
+/**
+ * This class is used to startup an AAS-Server using the AASServerComponent
+ * 
+ * @author conradi
+ *
+ */
+public class ExampleAASComponent {
+
+	public static final String CONTEXT_PATH = "aasComponent"; 
+	
+	private int port;
+	
+	private IAASRegistry registry;
+	
+	// Hold a reference to the server to be able to shut it down
+	private AASServerComponent aasServer = null;
+	
+	
+	public ExampleAASComponent(int port, IAASRegistry registry) {
+		this.port = port;
+		this.registry = registry;
+	}
+	
+	public void startupAASServer() {
+		// Create a Configuration telling the component the port to use and the contextPath
+		// The contextPath is attached to the address of the server "http://localhost:8080/{contextPath}"
+		BaSyxContextConfiguration contextConfig = new BaSyxContextConfiguration(port, CONTEXT_PATH);
+		aasServer = new AASServerComponent(contextConfig);
+		
+		// Set the registry to be used by the server
+		aasServer.setRegistry(registry);
+		
+		// Startup the AASServer
+		aasServer.startComponent();
+	}
+	
+	public void shutdownAASServer() {
+		// If an AASServer was started -> stop it
+		if(aasServer != null) {
+			aasServer.stopComponent();
+		}
+	}
+	
+	public String getAASServerPath() {
+		return "http://localhost:" + port + "/" + CONTEXT_PATH;
+	}
+}
diff --git a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/support/ExampleComponentBuilder.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/support/ExampleComponentBuilder.java
new file mode 100644
index 0000000..e4ddd69
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/support/ExampleComponentBuilder.java
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.support;
+
+import org.eclipse.basyx.aas.metamodel.api.parts.asset.AssetKind;
+import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.map.parts.Asset;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+
+/**
+ * This class is used to build AssetAdministrationShells and Submodels
+ * for the scenarios and snippets.
+ * 
+ * Please note that the generated objects are just for showcasing,
+ * several mandatory attributes are missing. 
+ * 
+ * @author conradi
+ *
+ */
+public class ExampleComponentBuilder {
+
+	public static final String PROPERTY_ID = "prop";
+	public static final int PROPERTY_VALUE = 123;
+
+	public static final String COLLECTION_ID = "collection";
+	public static final String COLLECTION_PROPERTY_ID = "propInCollection";
+	public static final String COLLECTION_PROPERTY_VALUE = "TheValue";
+	
+	/**
+	 * Builds a Submodel containing a Property and a Collection with a Property
+	 * 
+	 * @param idShort the idShort for the new Submodel
+	 * @return the new Submodel
+	 */
+	public static Submodel buildExampleSubmodel(String idShort, String id) {
+		Submodel submodel = new Submodel(idShort, new Identifier(IdentifierType.CUSTOM, id));
+		
+		// Add a Property to the Submodel
+		Property property = new Property(PROPERTY_ID, ValueType.Int32);
+		property.setValue(PROPERTY_VALUE);
+		submodel.addSubmodelElement(property);
+				
+		// Add a SubmodelElementCollection
+		SubmodelElementCollection collection = new SubmodelElementCollection(COLLECTION_ID);
+		
+		// Add a Property to the SubmodelElementCollection
+		Property property2 = new Property(COLLECTION_PROPERTY_ID, ValueType.String);
+		property2.setValue(COLLECTION_PROPERTY_VALUE);
+		collection.addSubmodelElement(property2);
+		submodel.addSubmodelElement(collection);
+		
+		return submodel;
+	}
+	
+	/**
+	 * Builds an AssetAdministrationShell
+	 * 
+	 * @param idShort the idShort for the new AAS
+	 * @param id the id to be used in Identification
+	 * @return the new AAS
+	 */
+	public static AssetAdministrationShell buildExampleAAS(String idShort, String id) {
+		Identifier aasIdentifier = new Identifier(IdentifierType.CUSTOM, id);
+		Identifier assetIdentifier = new Identifier(IdentifierType.CUSTOM, id + "asset");
+		Asset asset = new Asset(idShort + "asset", assetIdentifier, AssetKind.INSTANCE);
+		AssetAdministrationShell aas = new AssetAdministrationShell(idShort, aasIdentifier, asset);
+		
+		return aas;
+	}
+	
+}
diff --git a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/support/ExampleRegistryComponent.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/support/ExampleRegistryComponent.java
new file mode 100644
index 0000000..e26e1eb
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/support/ExampleRegistryComponent.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.support;
+
+import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
+import org.eclipse.basyx.components.registry.RegistryComponent;
+import org.eclipse.basyx.components.registry.configuration.BaSyxRegistryConfiguration;
+import org.eclipse.basyx.components.registry.configuration.RegistryBackend;
+
+/**
+ * This class is used to startup a registry using the RegistryComponent
+ * 
+ * @author conradi
+ *
+ */
+public class ExampleRegistryComponent {
+
+	public static final String CONTEXT_PATH = "registry";
+
+	private int port; 
+	
+	// Hold a reference to the server to be able to shut it down
+	private RegistryComponent registry = null;
+	
+	
+	public ExampleRegistryComponent(int port) {
+		this.port = port;
+	}
+	
+	
+	public void startupRegistry() {	
+		// Create a Configuration telling the component the port to use and the contextPath
+		// The contextPath is attached to the address of the server "http://localhost:8080/{contextPath}"
+		BaSyxContextConfiguration contextConfig = new BaSyxContextConfiguration(port, CONTEXT_PATH);
+		
+		// Create a RegistrationConfiguration telling the component to hold the whole registry in memory
+		BaSyxRegistryConfiguration registryConfig = new BaSyxRegistryConfiguration(RegistryBackend.INMEMORY);
+		
+		registry = new RegistryComponent(contextConfig, registryConfig);
+		
+		// Startup the Registry
+		registry.startComponent();
+	}
+	
+	public void shutdownRegistry() {
+		// If a registry was started -> stop it
+		if(registry != null) {
+			registry.stopComponent();
+		}
+	}
+	
+	public String getRegistryPath() {
+		return "http://localhost:" + port + "/" + CONTEXT_PATH;
+	}
+}
diff --git a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/support/directory/ExampleAASRegistry.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/support/directory/ExampleAASRegistry.java
index b4f894b..4bdf572 100644
--- a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/support/directory/ExampleAASRegistry.java
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/support/directory/ExampleAASRegistry.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.examples.support.directory;
 
 import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
@@ -23,8 +32,8 @@
 		IIdentifier smId = new Identifier(IdentifierType.IRI, submodelid);
 		SubmodelDescriptor smDes = new SubmodelDescriptor(submodelid, smId, endpoint);
 
-		if (descriptorMap.keySet().contains(aasUrn.getURN())) {
-			aasDescriptor = descriptorMap.get(aasUrn.getURN());
+		if (handler.contains(aasUrn)) {
+			aasDescriptor = handler.get(aasUrn);
 		} else {
 			throw new RuntimeException("AASDescriptor for " + rawAASUrn + " missing");
 		}
diff --git a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/support/directory/ExamplesPreconfiguredDirectory.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/support/directory/ExamplesPreconfiguredDirectory.java
index 3dd8b66..cf0214b 100644
--- a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/support/directory/ExamplesPreconfiguredDirectory.java
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/support/directory/ExamplesPreconfiguredDirectory.java
@@ -1,6 +1,15 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.examples.support.directory;
 
-import org.eclipse.basyx.vab.directory.memory.InMemoryDirectory;
+import org.eclipse.basyx.vab.registry.memory.VABInMemoryRegistry;
 
 /**
  * Implement the examples directory service with pre-configured directory entries
@@ -8,7 +17,7 @@
  * @author kuhn
  *
  */
-public class ExamplesPreconfiguredDirectory extends InMemoryDirectory {
+public class ExamplesPreconfiguredDirectory extends VABInMemoryRegistry {
 
 	
 	/**
@@ -20,6 +29,6 @@
 
 		// Define mappings
 		// - AAS server mapping
-		addMapping("AASServer", "http://localhost:8080/basys.examples/Components/BaSys/1.0/aasServer/");
+		addMapping("AASServer", "http://localhost:8080/basys.examples/Components/AasServer/");
 	}	
 }
diff --git a/examples/basys.examples/src/main/resources/CloudEdgeDeploymentScenarioAASContext.properties b/examples/basys.examples/src/main/resources/CloudEdgeDeploymentScenarioAASContext.properties
new file mode 100644
index 0000000..7151423
--- /dev/null
+++ b/examples/basys.examples/src/main/resources/CloudEdgeDeploymentScenarioAASContext.properties
@@ -0,0 +1,24 @@
+# ###############################
+# HTTP Context configuration file
+# ###############################
+
+# ###############################
+# Context Path
+# ###############################
+# Specifies the subpath in the url for this server context
+ 
+contextPath=/cloud
+
+# ###############################
+# Hostname
+# ###############################
+# Specifies the hostname for this server context
+
+contextHostname=localhost
+
+# ###############################
+# Port
+# ###############################
+# Specifies the port for this server context
+
+contextPort=8081
diff --git a/examples/basys.examples/src/main/resources/RegistryContext.properties b/examples/basys.examples/src/main/resources/RegistryContext.properties
new file mode 100644
index 0000000..c0c55e1
--- /dev/null
+++ b/examples/basys.examples/src/main/resources/RegistryContext.properties
@@ -0,0 +1,24 @@
+# ###############################
+# HTTP Context configuration file
+# ###############################
+
+# ###############################
+# Context Path
+# ###############################
+# Specifies the subpath in the url for this server context
+ 
+contextPath=/registry
+
+# ###############################
+# Hostname
+# ###############################
+# Specifies the hostname for this server context
+
+contextHostname=localhost
+
+# ###############################
+# Port
+# ###############################
+# Specifies the port for this server context
+
+contextPort=4000
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/TestContext.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/TestContext.java
deleted file mode 100644
index de4b882..0000000
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/TestContext.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package org.eclipse.basyx.examples;
-
-import org.eclipse.basyx.examples.contexts.BaSyxExamplesContext_1MemoryAASServer_1SQLDirectory;
-import org.eclipse.basyx.vab.protocol.http.server.BaSyxContext;
-
-/**
- * This class is used to define test context once for all the test projects.
- * So that multiple context does not get created
- * For now, only SQL context is created here
- * @author haque
- *
- */
-public class TestContext {
-	
-	// A new instance of SQL context used in all test project
-	public static BaSyxContext sqlContext = new BaSyxExamplesContext_1MemoryAASServer_1SQLDirectory();
-}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/contexts/BaSyxExamplesContext.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/contexts/BaSyxExamplesContext.java
new file mode 100644
index 0000000..cd5efd0
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/contexts/BaSyxExamplesContext.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.contexts;
+
+import org.eclipse.basyx.components.aas.servlet.AASAggregatorServlet;
+import org.eclipse.basyx.components.registry.servlet.InMemoryRegistryServlet;
+import org.eclipse.basyx.vab.protocol.http.server.BaSyxContext;
+
+/**
+ * BaSyx context that contains an Industrie 4.0 Servlet infrastructure <br>
+ * - One in-memory AAS Server that receives and hosts asset administration
+ * shells and submodels<br>
+ * - One in-memory registry that manages AAS and sub model registrations<br>
+ * 
+ * @author kuhn, schnicke
+ *
+ */
+public class BaSyxExamplesContext extends BaSyxContext {
+
+	
+	/**
+	 * Version of serialized instance
+	 */
+	private static final long serialVersionUID = 1L;
+
+	private static final String CONTEXT = "/basys.examples";
+	
+	private static final String AASSERVERFRAGMENT = "/Components/AasServer/";
+	public static final String AASSERVERURL = CONTEXT + AASSERVERFRAGMENT;
+
+	private static final String REGISTRYFRAGMENT = "/Components/Registry/";
+	public static final String REGISTRYURL = CONTEXT + REGISTRYFRAGMENT;
+
+	/**
+	 * Constructor
+	 */
+	public BaSyxExamplesContext() {
+		// Invoke base constructor to set up Tomcat server in basys.components context
+		super(CONTEXT, "");
+		
+		// Define Servlet infrastucture
+		addServletMapping(REGISTRYFRAGMENT + "*", new InMemoryRegistryServlet());
+		addServletMapping(AASSERVERFRAGMENT + "*", new AASAggregatorServlet());
+	}
+}
+
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/contexts/BaSyxExamplesContext_1MemoryAASServer_1SQLDirectory.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/contexts/BaSyxExamplesContext_1MemoryAASServer_1SQLDirectory.java
deleted file mode 100644
index 614da66..0000000
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/contexts/BaSyxExamplesContext_1MemoryAASServer_1SQLDirectory.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package org.eclipse.basyx.examples.contexts;
-
-import org.eclipse.basyx.components.servlet.SQLRegistryServlet;
-import org.eclipse.basyx.components.servlet.submodel.cfg.RawCFGSubModelProviderServlet;
-import org.eclipse.basyx.vab.protocol.http.server.BaSyxContext;
-
-/**
- * BaSyx context that contains an Industrie 4.0 Servlet infrastructure
- * - One in-memory AAS Server that receives and hosts asset administration shells and sub models
- * - One SQL directory that manages AAS and sub model registrations
- * 
- * @author kuhn
- *
- */
-public class BaSyxExamplesContext_1MemoryAASServer_1SQLDirectory extends BaSyxContext {
-
-	
-	/**
-	 * Version of serialized instance
-	 */
-	private static final long serialVersionUID = 1L;
-
-
-	
-	/**
-	 * Constructor
-	 */
-	public BaSyxExamplesContext_1MemoryAASServer_1SQLDirectory() {
-		// Invoke base constructor to set up Tomcat server in basys.components context
-		super("/basys.examples", "");
-		
-		// Define Servlet infrastucture
-		addServletMapping("/Components/Directory/SQL/*",       new SQLRegistryServlet().withParameter("config", "/WebContent/WEB-INF/config/directory/sqldirectory/directory.properties"));
-		addServletMapping("/Components/BaSys/1.0/aasServer/*", new RawCFGSubModelProviderServlet().withParameter("config", "/WebContent/WEB-INF/config/aasServer/aasServer.properties"));
-	}
-}
-
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/contexts/BaSyxExamplesContext_Empty.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/contexts/BaSyxExamplesContext_Empty.java
index f7ddbcb..6ff858c 100644
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/contexts/BaSyxExamplesContext_Empty.java
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/contexts/BaSyxExamplesContext_Empty.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.examples.contexts;
 
 import org.eclipse.basyx.vab.protocol.http.server.BaSyxContext;
@@ -16,14 +25,14 @@
 	 */
 	private static final long serialVersionUID = 1L;
 
-
+	public static final String CONTEXT = "/basys.examples";
 	
 	/**
 	 * Constructor
 	 */
 	public BaSyxExamplesContext_Empty() {
 		// Invoke base constructor to set up Tomcat server in basys.components context
-		super("/basys.examples", "");
+		super(CONTEXT, "");
 	}
 }
 
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/deployment/BaSyxDeployment.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/deployment/BaSyxDeployment.java
new file mode 100644
index 0000000..5df305a
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/deployment/BaSyxDeployment.java
@@ -0,0 +1,149 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.deployment;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.basyx.vab.protocol.http.server.BaSyxHTTPServer;
+import org.eclipse.basyx.vab.protocol.http.server.BaSyxContext;
+import org.eclipse.basyx.vab.service.api.BaSyxService;
+import org.junit.rules.ExternalResource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+
+
+/**
+ * This class represents a BaSyx deployment with servers / servlets and assets for running BaSyx examples
+ * 
+ * @author kuhn
+ *
+ */
+public class BaSyxDeployment extends ExternalResource {
+	
+	/**
+	 * Initiates a logger using the current class
+	 */
+	private static final Logger logger = LoggerFactory.getLogger(BaSyxDeployment.class);
+
+	
+	/**
+	 * Store context objects
+	 */
+	protected Object[] contextComponents = null;
+	
+	/**
+	 * Map runnable names to runnables
+	 */
+	protected Map<String, BaSyxService> contectRunnablesByName = new HashMap<>();
+	
+	/**
+	 * Deployment on HTTP server
+	 */
+	private BaSyxHTTPServer server;
+	
+	
+	
+	/**
+	 * Constructor - accept parameter of type BaSyxContext or Runnable
+	 */
+	public BaSyxDeployment(Object... components) {
+		// Store context objects
+		contextComponents = components;
+		
+		// Store runnable objects by name
+		for (Object obj: contextComponents) {
+			// Check component type
+			if (!(obj instanceof BaSyxService)) continue;
+			
+			// Add BaSyxContextRunnable to context
+			// - Cast object
+			BaSyxService contextRunnable = (BaSyxService) obj;
+			// - Add context runnable to map if it is named
+			if (contextRunnable.getName() == null) continue;
+			// - Add context runnable to map
+			contectRunnablesByName.put(contextRunnable.getName(), contextRunnable);
+		}
+	}
+	
+	
+	
+    /**
+     * Execute before a test case starts
+     */
+    @Override
+	protected void before() {
+    	// Iterate context components
+    	for (Object contextComponent: contextComponents) {
+    		// Process BaSyx context objects that run in a tomcat server
+    		if (contextComponent instanceof BaSyxContext) {
+    			// Get HTTP server resource
+				server = new BaSyxHTTPServer((BaSyxContext) contextComponent);
+				// - Start the server
+				server.start();
+    			// - Continue loop
+    			continue;
+    		}
+    		
+    		// Process runnables
+    		if (contextComponent instanceof BaSyxService) {
+    			// Execute runnable
+    			((BaSyxService) contextComponent).start();
+    			// - Continue loop
+    			continue;
+    		}
+    		
+    		logger.error("Error:"+contextComponent);
+    		
+    		// Unknown deployment context
+    		throw new UnknownContextComponentTypeException();
+    	}
+    }
+
+    
+    /**
+     * Execute after test case ends
+     */
+    @Override
+	protected void after() {
+    	// Iterate context components
+    	for (Object contextComponent: contextComponents) {
+    		// Process BaSyx context objects that run in a tomcat server
+    		if (contextComponent instanceof BaSyxContext) {
+				// - Shutdown the server
+				server.shutdown();
+    			// - Continue loop
+    			continue;
+    		}
+    		
+    		// Process runnables
+    		if (contextComponent instanceof BaSyxService) {
+    			// Execute runnable
+    			((BaSyxService) contextComponent).stop();
+    			// - Continue loop
+    			continue;
+    		}
+    		
+    		// Unknown deployment context
+    		throw new UnknownContextComponentTypeException();
+    	}
+    }
+    
+    
+    /**
+     * Get context runnable by name
+     */
+    public BaSyxService getRunnable(String name) {
+    	return contectRunnablesByName.get(name);
+    }
+}
+
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/deployment/UnknownContextComponentTypeException.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/deployment/UnknownContextComponentTypeException.java
new file mode 100644
index 0000000..d8e1bbf
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/deployment/UnknownContextComponentTypeException.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.deployment;
+
+
+/**
+ * This exception indicates the presence of an unknown component type in a BaSyx context
+ * 
+ * @author kuhn
+ *
+ */
+public class UnknownContextComponentTypeException extends RuntimeException {
+
+	
+	/**
+	 * Version information for serialized instances
+	 */
+	private static final long serialVersionUID = 1L;
+}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/mockup/application/ReceiveDeviceDashboardStatusApplication.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/mockup/application/ReceiveDeviceDashboardStatusApplication.java
index 303dc1c..8acf3ee 100644
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/mockup/application/ReceiveDeviceDashboardStatusApplication.java
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/mockup/application/ReceiveDeviceDashboardStatusApplication.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.examples.mockup.application;
 
 import java.util.Map;
@@ -7,11 +16,12 @@
 import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
 import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
 import org.eclipse.basyx.components.service.BaseBaSyxService;
+import org.eclipse.basyx.examples.contexts.BaSyxExamplesContext;
 import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
-import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
+import org.eclipse.basyx.submodel.restapi.MultiSubmodelElementProvider;
 import org.eclipse.basyx.vab.manager.VABConnectionManager;
 import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorFactory;
 
 /**
  * Example BaSys 4.0 application that monitors device (execution) status changes and device service invocation counters
@@ -34,10 +44,10 @@
 	 */
 	public ReceiveDeviceDashboardStatusApplication() {
 		// Create AAS registry for this service
-		setRegistry(new AASRegistryProxy("http://localhost:8080/basys.examples/Components/Directory/SQL"));
+		setRegistry(new AASRegistryProxy("http://localhost:8080/" + BaSyxExamplesContext.REGISTRYURL));
 		
 		// Service connection manager
-		setConnectionManager(new VABConnectionManager(new ExamplesPreconfiguredDirectory(), new HTTPConnectorProvider()));
+		setConnectionManager(new VABConnectionManager(new ExamplesPreconfiguredDirectory(), new HTTPConnectorFactory()));
 
 		// Register URNs of used objects
 		addShortcut("AAS",        new ModelUrn("urn:de.FHG:devices.es.iese:aas:1.0:3:x-509#001"));
@@ -56,7 +66,7 @@
 		// Create connection to device sub model
 		// - This code assumes that network location of device sub model does not change while application is running
 		AASDescriptor      aasDescriptor = getRegistry().lookupAAS(lookupURN("AAS"));
-		SubmodelDescriptor smDescriptor  = aasDescriptor.getSubModelDescriptor(lookupURN("Status"));
+		SubmodelDescriptor smDescriptor  = aasDescriptor.getSubmodelDescriptor(lookupURN("Status"));
 		// - Connect to status sub model end point
 		aasServerConnection = getConnectionManager().connectToVABElementByPath(smDescriptor.getFirstEndpoint());		
 	}
@@ -69,7 +79,7 @@
 	public String getDeviceStatus() {
 		// Read the status property
 		Map<String, Object> property = (Map<String, Object>) aasServerConnection
-				.getModelPropertyValue(SubmodelElementProvider.PROPERTIES + "/status");
+				.getValue(MultiSubmodelElementProvider.ELEMENTS + "/status");
 		// Return the value of the property
 		return property.get("value").toString();
 	}
@@ -82,7 +92,7 @@
 	public int getDeviceInvocationCounter() {
 		// Read the invocation counter for device default service
 		Map<String, Object> property = (Map<String, Object>) aasServerConnection
-				.getModelPropertyValue(SubmodelElementProvider.PROPERTIES + "/invocations");
+				.getValue(MultiSubmodelElementProvider.ELEMENTS + "/invocations");
 		// Return the value of the property
 		return (int) property.get("value");
 	}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/mockup/application/ReceiveDeviceMaintenanceApplication.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/mockup/application/ReceiveDeviceMaintenanceApplication.java
index e298ba6..f4de335 100644
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/mockup/application/ReceiveDeviceMaintenanceApplication.java
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/mockup/application/ReceiveDeviceMaintenanceApplication.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.examples.mockup.application;
 
 import java.util.Map;
@@ -7,11 +16,12 @@
 import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
 import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
 import org.eclipse.basyx.components.service.BaseBaSyxService;
+import org.eclipse.basyx.examples.contexts.BaSyxExamplesContext;
 import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
-import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
+import org.eclipse.basyx.submodel.restapi.MultiSubmodelElementProvider;
 import org.eclipse.basyx.vab.manager.VABConnectionManager;
 import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorFactory;
 
 
 
@@ -38,10 +48,10 @@
 	 */
 	public ReceiveDeviceMaintenanceApplication() {
 		// Create AAS registry for this service
-		setRegistry(new AASRegistryProxy("http://localhost:8080/basys.examples/Components/Directory/SQL"));
+		setRegistry(new AASRegistryProxy("http://localhost:8080/" + BaSyxExamplesContext.REGISTRYURL));
 		
 		// Service connection manager
-		setConnectionManager(new VABConnectionManager(new ExamplesPreconfiguredDirectory(), new HTTPConnectorProvider()));
+		setConnectionManager(new VABConnectionManager(new ExamplesPreconfiguredDirectory(), new HTTPConnectorFactory()));
 
 		// Register URNs of used objects
 		addShortcut("AAS",        new ModelUrn("urn:de.FHG:devices.es.iese:aas:1.0:3:x-509#001"));
@@ -60,7 +70,7 @@
 		// Create connection to device sub model
 		// - This code assumes that network location of device sub model does not change while application is running
 		AASDescriptor      aasDescriptor = getRegistry().lookupAAS(lookupURN("AAS"));
-		SubmodelDescriptor smDescriptor  = aasDescriptor.getSubModelDescriptor(lookupURN("Supply"));
+		SubmodelDescriptor smDescriptor  = aasDescriptor.getSubmodelDescriptor(lookupURN("Supply"));
 		// - Connect to status sub model end point
 		aasServerConnection = getConnectionManager().connectToVABElementByPath(smDescriptor.getFirstEndpoint());		
 	}
@@ -73,7 +83,7 @@
 	public int getDevicePartSupplyStatus() {
 		// Read the status property
 		Map<String, Object> property = (Map<String, Object>) aasServerConnection
-				.getModelPropertyValue(SubmodelElementProvider.PROPERTIES + "/partAvailability");
+				.getValue(MultiSubmodelElementProvider.ELEMENTS + "/partAvailability");
 		// Return the value of the property
 		return Integer.parseInt(property.get("value").toString());
 	}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/mockup/device/ControllableTCPDeviceMockup.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/mockup/device/ControllableTCPDeviceMockup.java
index eae11ba..b183b80 100644
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/mockup/device/ControllableTCPDeviceMockup.java
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/mockup/device/ControllableTCPDeviceMockup.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.examples.mockup.device;
 
 import org.eclipse.basyx.components.device.BaseTCPControllableDeviceAdapter;
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/mockup/device/SimpleTCPDeviceMockup.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/mockup/device/SimpleTCPDeviceMockup.java
index 04fbef3..2bbd879 100644
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/mockup/device/SimpleTCPDeviceMockup.java
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/mockup/device/SimpleTCPDeviceMockup.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.examples.mockup.device;
 
 import org.eclipse.basyx.components.device.BaseTCPDeviceAdapter;
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/mockup/device/SmartBaSyxTCPDeviceMockup.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/mockup/device/SmartBaSyxTCPDeviceMockup.java
index 0846b5c..834e8ed 100644
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/mockup/device/SmartBaSyxTCPDeviceMockup.java
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/mockup/device/SmartBaSyxTCPDeviceMockup.java
@@ -1,33 +1,46 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.examples.mockup.device;
 
 import java.util.Map;
 
+import org.eclipse.basyx.aas.aggregator.restapi.AASAggregatorProvider;
 import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
 import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
 import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
 import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
 import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
 import org.eclipse.basyx.components.device.BaseSmartDevice;
+import org.eclipse.basyx.examples.contexts.BaSyxExamplesContext;
 import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
 import org.eclipse.basyx.models.controlcomponent.ExecutionState;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
+import org.eclipse.basyx.submodel.restapi.MultiSubmodelElementProvider;
 import org.eclipse.basyx.vab.manager.VABConnectionManager;
 import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+import org.eclipse.basyx.vab.modelprovider.VABPathTools;
 import org.eclipse.basyx.vab.modelprovider.map.VABMapProvider;
 import org.eclipse.basyx.vab.protocol.basyx.server.BaSyxTCPServer;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorFactory;
 
 /**
  * This class implements a mockup of a smart manufacturing device
  * 
- * The device pushes its AAS to an external asset administration shell server
- * - The sub model "statusSM" is pushed to the external asset administration shell server as well
- * - The sub model "controllerSM" is provided by an BaSyx/TCP server of the smart device
+ * The device pushes its AAS to an external asset administration shell server -
+ * The sub model "statusSM" is pushed to the external asset administration shell
+ * server as well - The sub model "controllerSM" is provided by an BaSyx/TCP
+ * server of the smart device
  * 
  * @author kuhn
- *
+ * 
  */
 public class SmartBaSyxTCPDeviceMockup extends BaseSmartDevice {
 
@@ -49,6 +62,7 @@
 	 */
 	protected VABElementProxy aasServerConnection = null;
 
+	protected String aasPath;
 	
 	
 
@@ -68,8 +82,8 @@
 		addShortcut("Status",     new ModelUrn("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#001"));
 
 		// Configure BaSyx service - registry and connection manager
-		setRegistry(new AASRegistryProxy("http://localhost:8080/basys.examples/Components/Directory/SQL"));
-		setConnectionManager(new VABConnectionManager(new ExamplesPreconfiguredDirectory(), new HTTPConnectorProvider()));
+		setRegistry(new AASRegistryProxy("http://localhost:8080/" + BaSyxExamplesContext.REGISTRYURL));
+		setConnectionManager(new VABConnectionManager(new ExamplesPreconfiguredDirectory(), new HTTPConnectorFactory()));
 	}
 
 	
@@ -83,10 +97,9 @@
 		super.onServiceInvocation();
 		// Implement the device invocation counter - read and increment invocation counter
 		Map<String, Object> property = (Map<String, Object>) aasServerConnection
-				.getModelPropertyValue(
-						"/aas/submodels/Status/" + SubmodelElementProvider.PROPERTIES + "/invocations");
+				.getValue(aasPath + "/submodels/Status/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/invocations");
 		int invocations = (int) property.get("value");
-		aasServerConnection.setModelPropertyValue("/aas/submodels/Status/" + SubmodelElementProvider.PROPERTIES + "/invocations/value", ++invocations);
+		aasServerConnection.setValue(aasPath + "/submodels/Status/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/invocations/value", ++invocations);
 	}
 
 	
@@ -99,7 +112,7 @@
 		super.onChangedExecutionState(newExecutionState);
 		
 		// Update property "properties/status" in external AAS
-		aasServerConnection.setModelPropertyValue("/aas/submodels/Status/" + SubmodelElementProvider.PROPERTIES + "/status/value",
+		aasServerConnection.setValue(aasPath + "/submodels/Status/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/status/value",
 				newExecutionState.getValue());
 	}
 
@@ -121,27 +134,32 @@
 		
 		// Create device AAS
 		// - Create device AAS
-		AssetAdministrationShell aas = new AssetAdministrationShell().putPath("idShort", "DeviceIDShort");
+		AssetAdministrationShell aas = new AssetAdministrationShell();
+		aas.setIdShort("DeviceIDShort");
+		aas.setIdentification(lookupURN("AAS"));
+
 		// - Transfer device AAS to server
-		aasServerConnection.createValue("/aas", aas);
+		aasServerConnection.setValue(VABPathTools.append(AASAggregatorProvider.PREFIX, VABPathTools.encodePathElement(aas.getIdentification().getId())), aas);
+
+		aasPath = VABPathTools.concatenatePaths(AASAggregatorProvider.PREFIX, lookupURN("AAS").getEncodedURN(), "aas");
 
 		
 		// The device also brings a sub model structure with an own ID that is being pushed on the server
 		// - Create generic sub model and add properties
-		SubModel statusSM = new SubModel();
+		Submodel statusSM = new Submodel();
 		statusSM.setIdShort("Status");
 		//   - Property status: indicate device status
 		Property statusProp = new Property("offline");
 		statusProp.setIdShort("status");
-		statusSM.addSubModelElement(statusProp);
+		statusSM.addSubmodelElement(statusProp);
 		//   - Property statistics: export invocation statistics for every service
 		//     - invocations: indicate total service invocations. Properties are not persisted in this example,
 		//                    therefore we start counting always at 0.
 		Property invocationsProp = new Property(0);
 		invocationsProp.setIdShort("invocations");
-		statusSM.addSubModelElement(invocationsProp);
+		statusSM.addSubmodelElement(invocationsProp);
 		// - Transfer device sub model to server
-		aasServerConnection.createValue("/aas/submodels", statusSM);
+		aasServerConnection.setValue(aasPath + "/submodels/" + statusSM.getIdShort(), statusSM);
 
 		
 		// Register control component as local sub model
@@ -153,12 +171,12 @@
 		
 		// Register AAS and sub models in directory (push AAS descriptor to server)
 		// - AAS repository server URL
-		String aasRepoURL = "http://localhost:8080/basys.examples/Components/BaSys/1.0/aasServer/aas";
+		String aasRepoURL = "http://localhost:8080" + BaSyxExamplesContext.AASSERVERURL + "/" + AASAggregatorProvider.PREFIX + "/" + lookupURN("AAS").getEncodedURN() + "/aas";
 		// - Build an AAS descriptor, add sub model descriptors
 		AASDescriptor deviceAASDescriptor = new AASDescriptor(lookupURN("AAS"), aasRepoURL);
 		// Create sub model descriptors
 		SubmodelDescriptor statusSMDescriptor = new SubmodelDescriptor("Status", lookupURN("Status"),
-				aasRepoURL + "/submodels/Status");
+				aasRepoURL + "/submodels/Status/submodel");
 		// Add sub model descriptor to AAS descriptor
 		deviceAASDescriptor.addSubmodelDescriptor(statusSMDescriptor);
 		// - Push AAS descriptor to server
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/mockup/devicemanager/BaSyxTCPControlManufacturingDeviceManager.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/mockup/devicemanager/BaSyxTCPControlManufacturingDeviceManager.java
index d7939bf..e03740a 100644
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/mockup/devicemanager/BaSyxTCPControlManufacturingDeviceManager.java
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/mockup/devicemanager/BaSyxTCPControlManufacturingDeviceManager.java
@@ -1,22 +1,34 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.examples.mockup.devicemanager;
 
 import java.util.HashMap;
 
+import org.eclipse.basyx.aas.aggregator.restapi.AASAggregatorProvider;
 import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
 import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
 import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
 import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
 import org.eclipse.basyx.components.devicemanager.TCPControllableDeviceManagerComponent;
+import org.eclipse.basyx.examples.contexts.BaSyxExamplesContext;
 import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
 import org.eclipse.basyx.models.controlcomponent.ControlComponentChangeListener;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
+import org.eclipse.basyx.submodel.restapi.MultiSubmodelElementProvider;
 import org.eclipse.basyx.vab.manager.VABConnectionManager;
 import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+import org.eclipse.basyx.vab.modelprovider.VABPathTools;
 import org.eclipse.basyx.vab.modelprovider.map.VABMapProvider;
 import org.eclipse.basyx.vab.protocol.basyx.server.BaSyxTCPServer;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorFactory;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -29,7 +41,7 @@
  *
  */
 public class BaSyxTCPControlManufacturingDeviceManager extends TCPControllableDeviceManagerComponent implements ControlComponentChangeListener {
-	
+
 	/**
 	 * Initiates a logger using the current class
 	 */
@@ -40,6 +52,8 @@
 	 */
 	protected VABElementProxy aasServerConnection = null;
 
+	protected String aasPath;
+
 	
 	
 
@@ -52,18 +66,18 @@
 		
 		
 		// Set registry that will be used by this service
-		setRegistry(new AASRegistryProxy("http://localhost:8080/basys.examples/Components/Directory/SQL"));
+		setRegistry(new AASRegistryProxy("http://localhost:8080/" + BaSyxExamplesContext.REGISTRYURL));
 		
 		
 		// Set service connection manager and create AAS server connection
-		setConnectionManager(new VABConnectionManager(new ExamplesPreconfiguredDirectory(), new HTTPConnectorProvider()));
+		setConnectionManager(new VABConnectionManager(new ExamplesPreconfiguredDirectory(), new HTTPConnectorFactory()));
 		// - Create AAS server connection
 		aasServerConnection = getConnectionManager().connectToVABElement("AASServer");
 		
 		
 		// Set AAS server VAB object ID, AAS server URL, and AAS server path prefix
 		setAASServerObjectID("AASServer");
-		setAASServerURL("http://localhost:8080/basys.examples/Components/BaSys/1.0/aasServer");
+		setAASServerURL("http://localhost:8080/" + BaSyxExamplesContext.AASSERVERURL);
 	}
 
 	
@@ -76,7 +90,7 @@
 		super.start();
 		
 		// Create the device AAS and sub model structure
-		createDeviceAASAndSubModels();
+		createDeviceAASAndSubmodels();
 		
 		// Register AAS and sub model descriptors in directory (push AAS descriptor to server)
 		getRegistry().register(getAASDescriptor());
@@ -87,7 +101,7 @@
 	/**
 	 * Create the device AAS and sub model structure
 	 */
-	protected void createDeviceAASAndSubModels() {
+	protected void createDeviceAASAndSubmodels() {
 		// Register URNs of managed VAB objects
 		addShortcut("AAS",        new ModelUrn("urn:de.FHG:devices.es.iese:aas:1.0:3:x-509#001"));
 		addShortcut("Status",     new ModelUrn("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#001"));
@@ -96,30 +110,32 @@
 		AssetAdministrationShell aas = new AssetAdministrationShell();
 		// - Populate AAS
 		aas.setIdShort("DeviceIDShort");
+		aas.setIdentification(lookupURN("AAS"));
 	
 		// The device also brings a sub model structure with an own ID that is being pushed on the server
 		// - Create generic sub model and add properties
-		SubModel statusSM = new SubModel();
+		Submodel statusSM = new Submodel();
 		// - Set submodel ID
 		statusSM.setIdShort("Status");
 		//   - Property status: indicate device status
 		Property statusProp = new Property("offline");
 		statusProp.setIdShort("status");
-		statusSM.addSubModelElement(statusProp);
+		statusSM.addSubmodelElement(statusProp);
 		//   - Property statistics: export invocation statistics for every service
 		//     - invocations: indicate total service invocations. Properties are not persisted in this example,
 		//                    therefore we start counting always at 0.
 		Property invocationsProp = new Property(0);
 		invocationsProp.setIdShort("invocations");
-		statusSM.addSubModelElement(invocationsProp);
+		statusSM.addSubmodelElement(invocationsProp);
 		// - Add the submodel to the AAS
-		aas.addSubModel(statusSM);
+		aas.addSubmodel(statusSM);
 		
 		// Push the AAS and submodels to the server
 		// - Transfer device AAS to server
-		aasServerConnection.createValue("/aas", aas);
+		aasServerConnection.setValue(VABPathTools.append(AASAggregatorProvider.PREFIX, VABPathTools.encodePathElement(aas.getIdentification().getId())), aas);
 		// - Transfer device sub model to server
-		aasServerConnection.createValue("/aas/submodels", statusSM);
+		aasPath = AASAggregatorProvider.PREFIX + "/" + VABPathTools.encodePathElement(aas.getIdentification().getId()) + "/aas";
+		aasServerConnection.setValue(VABPathTools.concatenatePaths(aasPath, "submodels", statusSM.getIdShort()), statusSM);
 		
 		// Register URNs of control component VAB object
 		addShortcut("ControlComponent", new ModelUrn("urn:de.FHG:devices.es.iese:controlComponentSM:1.0:3:x-509#001"));
@@ -146,10 +162,10 @@
 	protected AASDescriptor getAASDescriptor() {
 		// Create AAS and sub model descriptors
 		AASDescriptor aasDescriptor = new AASDescriptor(lookupURN("AAS"), getAASEndpoint(lookupURN("AAS")));
-		addSubModelDescriptorURI(aasDescriptor, lookupURN("Status"), "Status");
+		addSubmodelDescriptorURI(aasDescriptor, lookupURN("Status"), "Status");
 		
 		// Add descriptor for control component sub model
-		addSubModelDescriptorURI(aasDescriptor, lookupURN("ControlComponent"),
+		addSubmodelDescriptorURI(aasDescriptor, lookupURN("ControlComponent"),
 				"basyx://127.0.0.1:" + controlComponentServerPort);
 		
 		// Return AAS, sub model descriptors, and added control component sub model descriptor
@@ -177,15 +193,15 @@
 		// Check what was being received. This check is performed based on a prefix that he device has to provide);
 		// - Update of device status
 		if (hasPrefix(rxStr, "status:"))
-			aasServerConnection.setModelPropertyValue("/aas/submodels/Status/" + SubmodelElementProvider.PROPERTIES + "/status/value", removePrefix(rxStr, "status"));
+			aasServerConnection.setValue(aasPath + "/submodels/Status/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/status/value", removePrefix(rxStr, "status"));
 		// - Device indicates service invocation
 		if (hasPrefix(rxStr, "invocation:")) {
 			// Start of process
 			if (hasPrefix(rxStr, "invocation:start")) {
 				// Read and increment invocation counter
-				HashMap<String, Object> property = (HashMap<String, Object>) aasServerConnection.getModelPropertyValue("/aas/submodels/Status/" + SubmodelElementProvider.PROPERTIES + "/invocations");
+				HashMap<String, Object> property = (HashMap<String, Object>) aasServerConnection.getValue(aasPath + "/submodels/Status/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/invocations");
 				int invocations = (int) property.get("value");
-				aasServerConnection.setModelPropertyValue("/aas/submodels/Status/" + SubmodelElementProvider.PROPERTIES + "/invocations/value", ++invocations);
+				aasServerConnection.setValue(aasPath + "/submodels/Status/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/invocations/value", ++invocations);
 			}
 			
 			// End of process
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/mockup/devicemanager/ManufacturingDeviceActiveAASManager.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/mockup/devicemanager/ManufacturingDeviceActiveAASManager.java
index 036d15a..9c81d3e 100644
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/mockup/devicemanager/ManufacturingDeviceActiveAASManager.java
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/mockup/devicemanager/ManufacturingDeviceActiveAASManager.java
@@ -1,8 +1,18 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.examples.mockup.devicemanager;
 
+import org.eclipse.basyx.aas.aggregator.restapi.AASAggregatorProvider;
 import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
 import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.AASLambdaPropertyHelper;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
 import org.eclipse.basyx.tools.aas.active.HTTPGetter;
@@ -33,9 +43,9 @@
 	 * Create the device AAS and sub model structure
 	 */
 	@Override
-	protected void createDeviceAASAndSubModels() {
+	protected void createDeviceAASAndSubmodels() {
 		// Invoke base implementation
-		super.createDeviceAASAndSubModels();
+		super.createDeviceAASAndSubmodels();
 		
 		
 		// Register URNs of managed VAB objects
@@ -43,7 +53,7 @@
 		
 
 		// Create sub model
-		SubModel supplySM = new SubModel();
+		Submodel supplySM = new Submodel();
 		// - Set submodel ID
 		supplySM.setIdShort("Supply");
 		//   - Property status: indicate device status
@@ -53,11 +63,11 @@
 		AASLambdaPropertyHelper.setLambdaValue(availabililtyProp,
 				new HTTPGetter("http://localhost:8080/basys.examples/Mockup/Supplier"), null);
 		availabililtyProp.setIdShort("partAvailability");
-		supplySM.addSubModelElement(availabililtyProp);
+		supplySM.addSubmodelElement(availabililtyProp);
 
 
 		// Transfer device sub model to server
-		aasServerConnection.createValue("/aas/submodels", supplySM);
+		aasServerConnection.setValue("/" + AASAggregatorProvider.PREFIX + "/" + lookupURN("AAS").getEncodedURN() + "/aas/submodels/" + supplySM.getIdShort(), supplySM);
 	}
 
 
@@ -68,8 +78,8 @@
 	protected AASDescriptor getAASDescriptor() {
 		// Create AAS and sub model descriptors
 		AASDescriptor aasDescriptor = new AASDescriptor(lookupURN("AAS"), getAASEndpoint(lookupURN("AAS")));
-		addSubModelDescriptorURI(aasDescriptor, lookupURN("Status"), "Status");
-		addSubModelDescriptorURI(aasDescriptor, lookupURN("Supply"), "Supply");
+		addSubmodelDescriptorURI(aasDescriptor, lookupURN("Status"), "Status");
+		addSubmodelDescriptorURI(aasDescriptor, lookupURN("Supply"), "Supply");
 		
 		// Return AAS and sub model descriptors
 		return aasDescriptor;
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/mockup/devicemanager/ManufacturingDeviceManager.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/mockup/devicemanager/ManufacturingDeviceManager.java
index 054f2fe..7fda3c0 100644
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/mockup/devicemanager/ManufacturingDeviceManager.java
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/mockup/devicemanager/ManufacturingDeviceManager.java
@@ -1,20 +1,32 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.examples.mockup.devicemanager;
 
 import java.util.HashMap;
 
+import org.eclipse.basyx.aas.aggregator.restapi.AASAggregatorProvider;
 import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
 import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
 import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
 import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
 import org.eclipse.basyx.components.configuration.CFGBaSyxProtocolType;
 import org.eclipse.basyx.components.devicemanager.TCPDeviceManagerComponent;
+import org.eclipse.basyx.examples.contexts.BaSyxExamplesContext;
 import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
+import org.eclipse.basyx.submodel.restapi.MultiSubmodelElementProvider;
 import org.eclipse.basyx.vab.manager.VABConnectionManager;
 import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
+import org.eclipse.basyx.vab.modelprovider.VABPathTools;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorFactory;
 
 /**
  * Example manufacturing device manager code
@@ -57,39 +69,24 @@
 		
 		// Configure this device manager
 		configure()
-			.registryURL("http://localhost:8080/basys.examples/Components/Directory/SQL")
+				.registryURL("http://localhost:8080/" + BaSyxExamplesContext.REGISTRYURL)
 			.connectionManagerType(CFGBaSyxProtocolType.HTTP)
 				.directoryService(new ExamplesPreconfiguredDirectory())
 			.end();
 		
-		// configure()
-		//   .registryURL()
-		//   .connectionManagerDirectory(new ExamplesPreconfiguredDirectory())
-		//   .connectionManagerProtocol(HTTP)
-		//   .AASServerObjectID(...)
-		//   .addAASAAS()
-		//   	.whateverAASProperty()
-		//   	.addSubmodel()
-		//			.property()
-		//			.endSubModel()
-		//		.end();
-		
-		
-		// configure(Map<>...)
-		
 		// Set registry that will be used by this service
-		setRegistry(new AASRegistryProxy("http://localhost:8080/basys.examples/Components/Directory/SQL"));
+		setRegistry(new AASRegistryProxy("http://localhost:8080/" + BaSyxExamplesContext.REGISTRYURL));
 		
 		
 		// Set service connection manager and create AAS server connection
-		setConnectionManager(new VABConnectionManager(new ExamplesPreconfiguredDirectory(), new HTTPConnectorProvider()));
+		setConnectionManager(new VABConnectionManager(new ExamplesPreconfiguredDirectory(), new HTTPConnectorFactory()));
 		// - Create AAS server connection
 		aasServerConnection = getConnectionManager().connectToVABElement("AASServer");
 		
 		
 		// Set AAS server VAB object ID, AAS server URL, and AAS server path prefix
 		setAASServerObjectID("AASServer");
-		setAASServerURL("http://localhost:8080/basys.examples/Components/BaSys/1.0/aasServer");
+		setAASServerURL("http://localhost:8080/" + BaSyxExamplesContext.AASSERVERURL);
 	}
 
 
@@ -103,7 +100,7 @@
 		super.start();
 		
 		// Create the device AAS and sub model structure
-		createDeviceAASAndSubModels();
+		createDeviceAASAndSubmodels();
 		
 		// Register AAS and sub model descriptors in directory (push AAS descriptor to server)
 		getRegistry().register(getAASDescriptor());
@@ -117,7 +114,7 @@
 	protected AASDescriptor getAASDescriptor() {
 		// Create AAS and sub model descriptors
 		AASDescriptor aasDescriptor = new AASDescriptor(lookupURN("AAS"), getAASEndpoint(lookupURN("AAS")));
-		addSubModelDescriptorURI(aasDescriptor, lookupURN("Status"), "Status");
+		addSubmodelDescriptorURI(aasDescriptor, lookupURN("Status"), "Status");
 		
 		// Return AAS and sub model descriptors
 		return aasDescriptor;
@@ -128,7 +125,7 @@
 	/**
 	 * Create the device AAS and sub model structure
 	 */
-	protected void createDeviceAASAndSubModels() {
+	protected void createDeviceAASAndSubmodels() {
 		// Register URNs of managed VAB objects
 		addShortcut("AAS",        new ModelUrn("urn:de.FHG:devices.es.iese:aas:1.0:3:x-509#001"));
 		addShortcut("Status",     new ModelUrn("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#001"));
@@ -137,27 +134,28 @@
 		AssetAdministrationShell aas = new AssetAdministrationShell();
 		// - Populate AAS
 		aas.setIdShort("DeviceIDShort");
+		aas.setIdentification(lookupURN("AAS"));
 		// - Transfer device AAS to server
-		aasServerConnection.createValue("/aas", aas);
+		aasServerConnection.setValue(VABPathTools.concatenatePaths(AASAggregatorProvider.PREFIX, VABPathTools.encodePathElement(aas.getIdentification().getId())), aas);
 
 	
 		// The device also brings a sub model structure with an own ID that is being pushed on the server
 		// - Create generic sub model and add properties
-		SubModel statusSM = new SubModel();
+		Submodel statusSM = new Submodel();
 		// - Set submodel ID
 		statusSM.setIdShort("Status");
 		//   - Property status: indicate device status
 		Property statusProp = new Property("offline");
 		statusProp.setIdShort("status");
-		statusSM.addSubModelElement(statusProp);
+		statusSM.addSubmodelElement(statusProp);
 		//   - Property statistics: export invocation statistics for every service
 		//     - invocations: indicate total service invocations. Properties are not persisted in this example,
 		//                    therefore we start counting always at 0.
 		Property invocationsProp = new Property(0);
 		invocationsProp.setIdShort("invocations");
-		statusSM.addSubModelElement(invocationsProp);
+		statusSM.addSubmodelElement(invocationsProp);
 		// - Transfer device sub model to server
-		aasServerConnection.createValue("/aas/submodels/", statusSM);
+		aasServerConnection.setValue(AASAggregatorProvider.PREFIX + "/" + VABPathTools.encodePathElement(lookupURN("AAS").getId()) + "/aas/submodels/" + statusSM.getIdShort(), statusSM);
 	}
 
 
@@ -174,6 +172,8 @@
 		// Do not process null values
 		if (rxData == null) return;
 		
+		String aasPath = "/" + AASAggregatorProvider.PREFIX + "/" + VABPathTools.encodePathElement(lookupURN("AAS").getId());
+
 		// Convert received data to string
 		String rxStr = new String(rxData); 
 		// - Trim string to remove possibly trailing and leading white spaces
@@ -182,15 +182,15 @@
 		// Check what was being received. This check is performed based on a prefix that he device has to provide);
 		// - Update of device status
 		if (hasPrefix(rxStr, "status:"))
-			aasServerConnection.setModelPropertyValue("/aas/submodels/Status/" + SubmodelElementProvider.PROPERTIES + "/status/value", removePrefix(rxStr, "status"));
+			aasServerConnection.setValue(aasPath + "/aas/submodels/Status/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/status/value", removePrefix(rxStr, "status"));
 		// - Device indicates service invocation
 		if (hasPrefix(rxStr, "invocation:")) {
 			// Start of process
 			if (hasPrefix(rxStr, "invocation:start")) {
 				// Read and increment invocation counter
-				HashMap<String, Object> property = (HashMap<String, Object>) aasServerConnection.getModelPropertyValue("/aas/submodels/Status/" + SubmodelElementProvider.PROPERTIES + "/invocations");
+				HashMap<String, Object> property = (HashMap<String, Object>) aasServerConnection.getValue(aasPath + "/aas/submodels/Status/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/invocations");
 				int invocations = (int) property.get("value");
-				aasServerConnection.setModelPropertyValue("/aas/submodels/Status/" + SubmodelElementProvider.PROPERTIES + "/invocations/value", ++invocations);
+				aasServerConnection.setValue(aasPath + "/aas/submodels/Status/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/invocations/value", ++invocations);
 			} 
 			// End of process
 			if (hasPrefix(rxStr, "invocation:end")) {
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/mockup/servers/SupplierStatusServlet.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/mockup/servers/SupplierStatusServlet.java
index 9cd4cce..37b643e 100644
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/mockup/servers/SupplierStatusServlet.java
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/mockup/servers/SupplierStatusServlet.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.examples.mockup.servers;
 
 
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/scenarios/cloudedgedeployment/TestCloudEdgeDeploymentScenario.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/scenarios/cloudedgedeployment/TestCloudEdgeDeploymentScenario.java
index 3459103..88a136e 100644
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/scenarios/cloudedgedeployment/TestCloudEdgeDeploymentScenario.java
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/scenarios/cloudedgedeployment/TestCloudEdgeDeploymentScenario.java
@@ -1,8 +1,17 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.examples.scenarios.cloudedgedeployment;
 
-import static org.junit.Assert.fail;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 
 import java.util.ArrayList;
 import java.util.Collection;
@@ -13,8 +22,10 @@
 import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
 import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
 import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
-import org.eclipse.basyx.aas.registration.api.IAASRegistryService;
-import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
+import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.junit.AfterClass;
 import org.junit.BeforeClass;
 import org.junit.Test;
 
@@ -27,15 +38,22 @@
 		scenario = new CloudEdgeDeploymentScenario();
 	}
 	
+	@AfterClass
+	public static void tearDown() {
+		scenario.stop();
+	}
+
+	private IAASRegistry getRegistry() {
+		return new AASRegistryProxy(CloudEdgeDeploymentScenario.registryPath);
+	}
+
 	/**
 	 * This tests if all the expected registry entries are present
 	 * 
 	 */
 	@Test
 	public void testRegistry() throws Exception {
-		IAASRegistryService registry = scenario.registry;
-		
-		List<AASDescriptor> aasDescriptors = registry.lookupAll();
+		List<AASDescriptor> aasDescriptors = getRegistry().lookupAll();
 		assertEquals(1, aasDescriptors.size());
 		
 		AASDescriptor aasDescriptor = aasDescriptors.get(0);
@@ -44,11 +62,11 @@
 		checkEndpoint(ComponentBuilder.AAS_ENDPOINT, aasDescriptor.getEndpoints());
 		
 		// Check if aasDescriptor has the correct number of SMDescriptors
-		assertEquals(2, aasDescriptor.getSubModelDescriptors().size());
+		assertEquals(2, aasDescriptor.getSubmodelDescriptors().size());
 		
 		// Iterate over the Collection of SMDescriptors and
 		// test if both have the expected idShort and endpoint
-		for(SubmodelDescriptor smDescriptor: aasDescriptor.getSubModelDescriptors()) {
+		for(SubmodelDescriptor smDescriptor: aasDescriptor.getSubmodelDescriptors()) {
 			if(smDescriptor.getIdShort().equals(ComponentBuilder.EDGESM_ID_SHORT)) {
 				checkEndpoint(ComponentBuilder.EDGESM_ENDPOINT, smDescriptor.getEndpoints());
 			} else if(smDescriptor.getIdShort().equals(ComponentBuilder.DOCUSM_ID_SHORT)) {
@@ -68,15 +86,15 @@
 	@Test
 	public void testAAS() throws Exception {
 		ConnectedAssetAdministrationShellManager manager =
-				new ConnectedAssetAdministrationShellManager(scenario.registry);
+				new ConnectedAssetAdministrationShellManager(getRegistry());
 		
-		IAssetAdministrationShell aas = manager.retrieveAAS(scenario.aasIdentifier);
+		IAssetAdministrationShell aas = manager.retrieveAAS(CloudEdgeDeploymentScenario.aasIdentifier);
 		
 		// Check if it has the correct idShort
 		assertEquals(ComponentBuilder.AAS_ID_SHORT, aas.getIdShort());
 		
 		// Get the Submodels and check if both expected SMs are present 
-		Map<String, ISubModel> submodels = aas.getSubModels();
+		Map<String, ISubmodel> submodels = aas.getSubmodels();
 		
 		assertTrue(submodels.containsKey(ComponentBuilder.EDGESM_ID_SHORT));
 		assertTrue(submodels.containsKey(ComponentBuilder.DOCUSM_ID_SHORT));
@@ -90,9 +108,9 @@
 	@Test
 	public void testDocuSM() {
 		ConnectedAssetAdministrationShellManager manager =
-				new ConnectedAssetAdministrationShellManager(scenario.registry);
+				new ConnectedAssetAdministrationShellManager(getRegistry());
 		
-		ISubModel docuSM = manager.retrieveSubModel(scenario.aasIdentifier, scenario.docuSmIdentifier);
+		ISubmodel docuSM = manager.retrieveSubmodel(CloudEdgeDeploymentScenario.aasIdentifier, CloudEdgeDeploymentScenario.docuSmIdentifier);
 		
 		// Check if it has the correct idShort, and 1 SubmodelElement
 		assertEquals(ComponentBuilder.DOCUSM_ID_SHORT, docuSM.getIdShort());
@@ -107,9 +125,9 @@
 	@Test
 	public void testEdgeSM() {
 		ConnectedAssetAdministrationShellManager manager =
-				new ConnectedAssetAdministrationShellManager(scenario.registry);
+				new ConnectedAssetAdministrationShellManager(getRegistry());
 		
-		ISubModel edgeSM = manager.retrieveSubModel(scenario.aasIdentifier, scenario.edgeSmIdentifier);
+		ISubmodel edgeSM = manager.retrieveSubmodel(CloudEdgeDeploymentScenario.aasIdentifier, CloudEdgeDeploymentScenario.edgeSmIdentifier);
 		
 		// Check if it has the correct idShort, and 1 SubmodelElement
 		assertEquals(ComponentBuilder.EDGESM_ID_SHORT, edgeSM.getIdShort());
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/scenarios/device/BaSyxExampleScenario.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/scenarios/device/BaSyxExampleScenario.java
new file mode 100644
index 0000000..00ef945
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/scenarios/device/BaSyxExampleScenario.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.scenarios.device;
+
+import java.util.function.Supplier;
+
+
+
+/**
+ * Base class for all BaSyx examples
+ * 
+ * @author kuhn
+ */
+public class BaSyxExampleScenario {
+
+	
+	
+	/**
+	 * Wait for a condition
+	 */
+	protected void waitfor(Supplier<Boolean> function) {
+		while (!function.get()) Thread.yield();
+	}
+}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/scenarios/device/RunSimpleTCPDevice.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/scenarios/device/RunSimpleTCPDevice.java
index b9a3059..9a7dd1e 100644
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/scenarios/device/RunSimpleTCPDevice.java
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/scenarios/device/RunSimpleTCPDevice.java
@@ -1,16 +1,24 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.examples.scenarios.device;
 
 import static org.junit.Assert.assertTrue;
 
-import org.eclipse.basyx.examples.contexts.BaSyxExamplesContext_1MemoryAASServer_1SQLDirectory;
+import org.eclipse.basyx.examples.contexts.BaSyxExamplesContext;
 import org.eclipse.basyx.examples.deployment.BaSyxDeployment;
-import org.eclipse.basyx.examples.examplescenario.BaSyxExampleScenario;
 import org.eclipse.basyx.examples.mockup.application.ReceiveDeviceDashboardStatusApplication;
 import org.eclipse.basyx.examples.mockup.device.SimpleTCPDeviceMockup;
 import org.eclipse.basyx.examples.mockup.devicemanager.ManufacturingDeviceManager;
 import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
 import org.eclipse.basyx.vab.manager.VABConnectionManager;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorFactory;
 import org.junit.ClassRule;
 import org.junit.Test;
 
@@ -33,7 +41,7 @@
 	/**
 	 * VAB connection manager backend
 	 */
-	protected VABConnectionManager connManager = new VABConnectionManager(new ExamplesPreconfiguredDirectory(), new HTTPConnectorProvider());
+	protected VABConnectionManager connManager = new VABConnectionManager(new ExamplesPreconfiguredDirectory(), new HTTPConnectorFactory());
 
 
 	/**
@@ -44,7 +52,7 @@
 	public static BaSyxDeployment context = new BaSyxDeployment(
 				// Simulated servlets
 				// - BaSys topology with one AAS Server and one SQL directory
-				new BaSyxExamplesContext_1MemoryAASServer_1SQLDirectory(),
+				new BaSyxExamplesContext(),
 				
 				// Simulated runnables
 				// - Manufacturing device manager, e.g. deployed to additonal device
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/scenarios/device/aas/RunAASDevice.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/scenarios/device/aas/RunAASDevice.java
index 8431a2f..8565440 100644
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/scenarios/device/aas/RunAASDevice.java
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/scenarios/device/aas/RunAASDevice.java
@@ -1,17 +1,26 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.examples.scenarios.device.aas;
 
 import static org.junit.Assert.assertTrue;
 
-import org.eclipse.basyx.examples.contexts.BaSyxExamplesContext_1MemoryAASServer_1SQLDirectory;
+import org.eclipse.basyx.examples.contexts.BaSyxExamplesContext;
 import org.eclipse.basyx.examples.deployment.BaSyxDeployment;
-import org.eclipse.basyx.examples.examplescenario.BaSyxExampleScenario;
 import org.eclipse.basyx.examples.mockup.application.ReceiveDeviceMaintenanceApplication;
 import org.eclipse.basyx.examples.mockup.device.SimpleTCPDeviceMockup;
 import org.eclipse.basyx.examples.mockup.devicemanager.ManufacturingDeviceActiveAASManager;
 import org.eclipse.basyx.examples.mockup.servers.SupplierStatusServlet;
+import org.eclipse.basyx.examples.scenarios.device.BaSyxExampleScenario;
 import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
 import org.eclipse.basyx.vab.manager.VABConnectionManager;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorFactory;
 import org.junit.ClassRule;
 import org.junit.Test;
 
@@ -29,7 +38,7 @@
 	/**
 	 * VAB connection manager backend
 	 */
-	protected VABConnectionManager connManager = new VABConnectionManager(new ExamplesPreconfiguredDirectory(), new HTTPConnectorProvider());
+	protected VABConnectionManager connManager = new VABConnectionManager(new ExamplesPreconfiguredDirectory(), new HTTPConnectorFactory());
 
 
 	/**
@@ -40,7 +49,7 @@
 	public static BaSyxDeployment context = new BaSyxDeployment(
 				// Simulated servlets
 				// - BaSys topology with one AAS Server and one SQL directory
-			new BaSyxExamplesContext_1MemoryAASServer_1SQLDirectory().
+				new BaSyxExamplesContext().
 					// Define additional scenario specific Servlets
 					addServletMapping("/Mockup/Supplier/*", new SupplierStatusServlet()),
 				
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/scenarios/device/controllable/RunExampleSimpleControllableTCPDevice.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/scenarios/device/controllable/RunExampleSimpleControllableTCPDevice.java
index 2559370..5318e53 100644
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/scenarios/device/controllable/RunExampleSimpleControllableTCPDevice.java
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/scenarios/device/controllable/RunExampleSimpleControllableTCPDevice.java
@@ -1,19 +1,30 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.examples.scenarios.device.controllable;
 
 import static org.junit.Assert.assertTrue;
 
-import org.eclipse.basyx.examples.contexts.BaSyxExamplesContext_1MemoryAASServer_1SQLDirectory;
+import org.eclipse.basyx.examples.contexts.BaSyxExamplesContext;
 import org.eclipse.basyx.examples.deployment.BaSyxDeployment;
-import org.eclipse.basyx.examples.examplescenario.BaSyxExampleScenario;
 import org.eclipse.basyx.examples.mockup.application.ReceiveDeviceDashboardStatusApplication;
 import org.eclipse.basyx.examples.mockup.device.ControllableTCPDeviceMockup;
 import org.eclipse.basyx.examples.mockup.devicemanager.BaSyxTCPControlManufacturingDeviceManager;
+import org.eclipse.basyx.examples.scenarios.device.BaSyxExampleScenario;
 import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
+import org.eclipse.basyx.models.controlcomponent.ControlComponent;
 import org.eclipse.basyx.models.controlcomponent.ExecutionState;
 import org.eclipse.basyx.vab.coder.json.connector.JSONConnector;
 import org.eclipse.basyx.vab.manager.VABConnectionManager;
+import org.eclipse.basyx.vab.modelprovider.VABPathTools;
 import org.eclipse.basyx.vab.protocol.basyx.connector.BaSyxConnector;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorFactory;
 import org.junit.ClassRule;
 import org.junit.Test;
 
@@ -29,7 +40,7 @@
 	/**
 	 * VAB connection manager backend
 	 */
-	protected VABConnectionManager connManager = new VABConnectionManager(new ExamplesPreconfiguredDirectory(), new HTTPConnectorProvider());
+	protected VABConnectionManager connManager = new VABConnectionManager(new ExamplesPreconfiguredDirectory(), new HTTPConnectorFactory());
 
 	
 	/**
@@ -54,7 +65,7 @@
 	public static BaSyxDeployment context = new BaSyxDeployment(
 				// BaSyx infrastructure
 				// - BaSys topology with one AAS Server and one SQL directory
-			new BaSyxExamplesContext_1MemoryAASServer_1SQLDirectory(),
+				new BaSyxExamplesContext(),
 				
 				// Simulated runnables
 				// - Manufacturing device manager, e.g. deployed to additonal device
@@ -94,7 +105,7 @@
 
 		
 		// Change device operation mode
-		toControlComponent.setModelPropertyValue("status/opMode", "RegularMilling");
+		toControlComponent.setValue(VABPathTools.concatenatePaths(ControlComponent.STATUS, ControlComponent.OP_MODE), "RegularMilling");
 		// - Validate device operation mode
 		waitfor(() -> ((ControllableTCPDeviceMockup) context.getRunnable("Device")).getOpMode().equals("RegularMilling"));
 
@@ -103,7 +114,7 @@
 
 		
 		// Start device service
-		toControlComponent.setModelPropertyValue("cmd", "start");
+		toControlComponent.setValue("cmd", "start");
 		// - Application waits for status change
 		waitfor( () -> ((ReceiveDeviceDashboardStatusApplication) context.getRunnable("Application")).getDeviceStatus().equals("EXECUTE") );
 		// - Validate device status
@@ -119,7 +130,7 @@
 
 
 		// Reset device to enable subsequent service calls
-		toControlComponent.setModelPropertyValue("cmd", "reset");
+		toControlComponent.setValue("cmd", "reset");
 		// - Application waits for status change
 		waitfor( () -> ((ReceiveDeviceDashboardStatusApplication) context.getRunnable("Application")).getDeviceStatus().equals("RESETTING") );
 		// - Validate device status
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/scenarios/device/controllable/RunExampleSimpleSmartDevice.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/scenarios/device/controllable/RunExampleSimpleSmartDevice.java
index 1309ddb..04bb917 100644
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/scenarios/device/controllable/RunExampleSimpleSmartDevice.java
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/scenarios/device/controllable/RunExampleSimpleSmartDevice.java
@@ -1,18 +1,29 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.examples.scenarios.device.controllable;
 
 import static org.junit.Assert.assertTrue;
 
-import org.eclipse.basyx.examples.contexts.BaSyxExamplesContext_1MemoryAASServer_1SQLDirectory;
+import org.eclipse.basyx.examples.contexts.BaSyxExamplesContext;
 import org.eclipse.basyx.examples.deployment.BaSyxDeployment;
-import org.eclipse.basyx.examples.examplescenario.BaSyxExampleScenario;
 import org.eclipse.basyx.examples.mockup.application.ReceiveDeviceDashboardStatusApplication;
 import org.eclipse.basyx.examples.mockup.device.SmartBaSyxTCPDeviceMockup;
+import org.eclipse.basyx.examples.scenarios.device.BaSyxExampleScenario;
 import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
+import org.eclipse.basyx.models.controlcomponent.ControlComponent;
 import org.eclipse.basyx.models.controlcomponent.ExecutionState;
 import org.eclipse.basyx.vab.coder.json.connector.JSONConnector;
 import org.eclipse.basyx.vab.manager.VABConnectionManager;
+import org.eclipse.basyx.vab.modelprovider.VABPathTools;
 import org.eclipse.basyx.vab.protocol.basyx.connector.BaSyxConnector;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorFactory;
 import org.junit.ClassRule;
 import org.junit.Test;
 
@@ -28,7 +39,7 @@
 	/**
 	 * VAB connection manager backend
 	 */
-	protected VABConnectionManager connManager = new VABConnectionManager(new ExamplesPreconfiguredDirectory(), new HTTPConnectorProvider());
+	protected VABConnectionManager connManager = new VABConnectionManager(new ExamplesPreconfiguredDirectory(), new HTTPConnectorFactory());
 
 	
 	/**
@@ -53,7 +64,7 @@
 	public static BaSyxDeployment context = new BaSyxDeployment(
 				// BaSyx infrastructure
 				// - BaSys topology with one AAS Server and one SQL directory
-			new BaSyxExamplesContext_1MemoryAASServer_1SQLDirectory(),
+				new BaSyxExamplesContext(),
 				
 				// Device mockups
 				new SmartBaSyxTCPDeviceMockup(9997).setName("Device"),
@@ -87,7 +98,7 @@
 		
 		
 		// Change device operation mode
-		toControlComponent.setModelPropertyValue("status/opMode", "RegularMilling");
+		toControlComponent.setValue(VABPathTools.concatenatePaths(ControlComponent.STATUS, ControlComponent.OP_MODE), "RegularMilling");
 		// - Validate device control component operation mode
 		waitfor( () -> ((SmartBaSyxTCPDeviceMockup) context.getRunnable("Device")).getControlComponent().getOperationMode().equals("RegularMilling") );
 
@@ -96,7 +107,7 @@
 
 
 		// Start device service
-		toControlComponent.setModelPropertyValue("cmd", "start");
+		toControlComponent.setValue("cmd", "start");
 		// - Validate control component status
 		waitfor( () -> ((SmartBaSyxTCPDeviceMockup) context.getRunnable("Device")).getControlComponent().getExecutionState().equals(ExecutionState.EXECUTE.getValue()) );
 		// - Indicate service end
@@ -106,7 +117,7 @@
 
 		
 		// Reset device to enable subsequent service calls
-		toControlComponent.setModelPropertyValue("cmd", "reset");
+		toControlComponent.setValue("cmd", "reset");
 		// - Device finishes reset and moves to idle state
 		((SmartBaSyxTCPDeviceMockup) context.getRunnable("Device")).resetCompleted();
 		
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/scenarios/staticdynamic/TestStaticDynamicScenario.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/scenarios/staticdynamic/TestStaticDynamicScenario.java
new file mode 100644
index 0000000..80b7366
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/scenarios/staticdynamic/TestStaticDynamicScenario.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.scenarios.staticdynamic;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Map;
+
+import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
+import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * Test for StaticDynamicScenario
+ * 
+ * @author conradi
+ *
+ */
+public class TestStaticDynamicScenario {
+
+	private static StaticDynamicScenario scenario;
+	
+	@BeforeClass
+	public static void startup() throws Exception {
+		scenario = new StaticDynamicScenario();
+	}
+	
+	@AfterClass
+	public static void tearDown() {
+		scenario.stop();
+	}
+	
+	@Test
+	public void checkDynamicSubmodel() throws Exception {
+		
+		AASRegistryProxy proxy = new AASRegistryProxy(StaticDynamicScenario.REGISTRY_URL);
+		ConnectedAssetAdministrationShellManager manager = new ConnectedAssetAdministrationShellManager(proxy);
+		
+		Identifier AASIdentifier = new Identifier(IdentifierType.IRI, StaticDynamicScenario.AAS_ID);
+		
+		Map<String, ISubmodel> submodels = manager.retrieveSubmodels(AASIdentifier);
+		
+		// The aas should contain 6 SMs
+		assertEquals(6, submodels.size());
+		
+		ISubmodel staticSM = submodels.get(ExampleDynamicSubmodel.SM_ID_SHORT);
+		
+		// Get the Property from the Submodel
+		IProperty smElement = (IProperty) staticSM.getSubmodelElements().get(ExampleDynamicSubmodel.PROPERTY_ID_SHORT);
+
+		// Check if the Property contains the correct value
+		assertEquals(ExampleDynamicSubmodel.PROPERTY_VALUE, smElement.getValue());
+	}
+}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/AbstractSnippetTest.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/AbstractSnippetTest.java
new file mode 100644
index 0000000..d5b02a9
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/AbstractSnippetTest.java
@@ -0,0 +1,85 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets;
+
+import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
+import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
+import org.eclipse.basyx.examples.support.ExampleAASComponent;
+import org.eclipse.basyx.examples.support.ExampleComponentBuilder;
+import org.eclipse.basyx.examples.support.ExampleRegistryComponent;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.junit.After;
+import org.junit.Before;
+
+/**
+ * This class provides the server environment required by all snippet test
+ * 
+ * @author conradi
+ *
+ */
+public abstract class AbstractSnippetTest {
+	
+
+	protected static final String AAS_ID_SHORT = "aasIdShort";
+	protected static final String AAS_ID = "aasId";
+	protected static final String AAS_ENDPOINT = "http://localhost:8080/aasComponent/shells/" + AAS_ID + "/aas";
+	
+	protected static final String SM_ID_SHORT = "smIdShort";
+	protected static final String SM_ID = "smId";
+	protected static final String SM_ENDPOINT = AAS_ENDPOINT + "/submodels/" + SM_ID_SHORT + "/submodel";
+	
+	protected ExampleAASComponent aasComponent;
+	protected ExampleRegistryComponent registryComponent;
+	
+	@Before
+	public void setupServers() {
+		registryComponent = new ExampleRegistryComponent(8081);
+		registryComponent.startupRegistry();
+		aasComponent = new ExampleAASComponent(8080, new AASRegistryProxy(registryComponent.getRegistryPath()));
+		aasComponent.startupAASServer();
+		
+		// Populate the Server with an example AAS/SM
+		populateServer();
+	}
+	
+	@After
+	public void shutdownServers() {
+		aasComponent.shutdownAASServer();
+		registryComponent.shutdownRegistry();
+	}
+	
+	/**
+	 * Pushes and registers an AAS and a Submodel to the test server
+	 */
+	private void populateServer() {
+		ConnectedAssetAdministrationShellManager manager = getManager();
+		
+		// Get the example AAS and Submodel
+		AssetAdministrationShell aas = ExampleComponentBuilder.buildExampleAAS(AAS_ID_SHORT, AAS_ID);
+		Submodel sm = ExampleComponentBuilder.buildExampleSubmodel(SM_ID_SHORT, SM_ID);
+		
+		// Push and register the AAS
+		manager.createAAS(aas, aasComponent.getAASServerPath());
+		
+		// Push and register the Submodel
+		manager.createSubmodel(aas.getIdentification(), sm);
+	}
+	
+	/**
+	 * Creates a ConnectedAASManager using the started registryComponent
+	 * 
+	 * @return the created ConnectedAASManager
+	 */
+	protected ConnectedAssetAdministrationShellManager getManager() {
+		AASRegistryProxy registryProxy = new AASRegistryProxy(registryComponent.getRegistryPath());
+		return new ConnectedAssetAdministrationShellManager(registryProxy);
+	}
+}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/AccessAASProperties.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/AccessAASProperties.java
deleted file mode 100644
index c6347e1..0000000
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/AccessAASProperties.java
+++ /dev/null
@@ -1,43 +0,0 @@
-package org.eclipse.basyx.examples.snippets.aas;
-
-import static org.junit.Assert.assertTrue;
-
-import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
-import org.junit.Test;
-
-/**
- * This code snippet illustrates the creation of an Asset Administration Shell (AAS) data structure 
- * and how to access its properties via different kinds of access operations
- * 
- * @author kuhn
- *
- */
-public class AccessAASProperties {
-
-		
-	/**
-	 * Code snippet that illustrates the instantiation and use of AAS
-	 */
-	@Test
-	public void snippet() throws Exception {
-		
-		// Create Asset Administration Shell
-		AssetAdministrationShell aas = new AssetAdministrationShell();
-		
-		// Access predefined AAS properties
-		// - Set AAS property via generic access method. For the generic access method,
-		//   the user must know the name of the accessed property. This kind of access
-		//   is discouraged, as it is not portable to new meta model versions. However,
-		//   it is illustrated for completeness.
-		aas.put("idShort", "DeviceIDShort");
-		// - Access AAS property via the specific access operation. This is the preferred
-		//   approach for accessing Asset Administration Shell and sub model properties,
-		//   as well as meta data.
-		Object deviceIDValue = aas.getIdShort();
-		
-		
-		// Compared received value to expected value
-		assertTrue(deviceIDValue.equals("DeviceIDShort"));
-	}
-}
-
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/CreateAAS.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/CreateAAS.java
deleted file mode 100644
index d2afd50..0000000
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/CreateAAS.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package org.eclipse.basyx.examples.snippets.aas;
-
-import static org.junit.Assert.assertEquals;
-
-import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
-import org.junit.Test;
-
-/**
- * Code snippet that illustrates the creation of an Asset Administration Shell (AAS) by extending an SDK class
- * 
- * @author kuhn
- *
- */
-public class CreateAAS {
-
-	
-	/**
-	 * Example Asset Administration Shell
-	 */
-	static class ExampleAssetAdministrationShell extends AssetAdministrationShell {
-		/**
-		 * Constructor
-		 */
-		public ExampleAssetAdministrationShell() {
-			// Set Asset Administration Shell ID
-			setIdShort("aas-001");
-		}
-	}
-	
-	/**
-	 * Run code snippet. Connect to AAS on server, access AAS properties. 
-	 */
-	@Test
-	public void createAAS() throws Exception {
-		// Create Asset Administration Shell
-		ExampleAssetAdministrationShell aas = new ExampleAssetAdministrationShell();
-		
-		// Retrieve AAS ID value
-		Object propertyId = aas.getIdShort();
-		
-		
-		// Check result
-		assertEquals("aas-001", propertyId);
-	}
-}
-
-
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/TestAddSubmodelToAAS.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/TestAddSubmodelToAAS.java
new file mode 100644
index 0000000..5af9acf
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/TestAddSubmodelToAAS.java
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.aas;
+
+import static org.junit.Assert.assertEquals;
+
+import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
+import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
+import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
+import org.eclipse.basyx.examples.snippets.AbstractSnippetTest;
+import org.eclipse.basyx.examples.support.ExampleComponentBuilder;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.junit.Test;
+
+/**
+ * Test for the AddSubmodelToAAS snippet
+ * 
+ * @author conradi
+ *
+ */
+public class TestAddSubmodelToAAS extends AbstractSnippetTest {
+
+	private static final String NEW_SM_ID_SHORT = "smIdShort_New";
+	private static final String NEW_SM_ID = "smId_New";
+	
+	private static final String NEW_SM_ENDPOINT = AAS_ENDPOINT + "/submodels/" + NEW_SM_ID_SHORT + "/submodel";
+	
+	@Test
+	public void testAddSubmodelToAAS() {
+		
+		// Get the example AAS and Submodel
+		Submodel submodel = ExampleComponentBuilder.buildExampleSubmodel(NEW_SM_ID_SHORT, NEW_SM_ID);
+
+		// Get the Identifiers for the AAS and the Submodel
+		IIdentifier aasIdentifier = new Identifier(IdentifierType.CUSTOM, AAS_ID);
+		IIdentifier smIdentifier = submodel.getIdentification();
+		
+		// Get the AAS as ConnectedAAS
+		ConnectedAssetAdministrationShellManager manager = getManager();
+		IAssetAdministrationShell aas = manager.retrieveAAS(aasIdentifier);
+		
+		// Add the Submodel to the AAS
+		AddSubmodelToAAS.addSubmodelToAAS(submodel, aas);
+		
+		
+		// Register the new Submodel
+		// This needs to be done to be able to retrieve it again
+		AASRegistryProxy registry = new AASRegistryProxy(registryComponent.getRegistryPath());
+		registry.register(aasIdentifier, new SubmodelDescriptor(submodel, NEW_SM_ENDPOINT));
+		
+		
+		// Check if the Submodel was correctly added
+		ISubmodel remoteSM = manager.retrieveSubmodel(aasIdentifier, smIdentifier);
+		assertEquals(NEW_SM_ID_SHORT, remoteSM.getIdShort());
+		
+	}
+	
+}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/TestCreateAAS.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/TestCreateAAS.java
new file mode 100644
index 0000000..57ba057
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/TestCreateAAS.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.aas;
+
+import static org.junit.Assert.assertEquals;
+
+import org.eclipse.basyx.aas.metamodel.api.parts.asset.AssetKind;
+import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.map.parts.Asset;
+import org.eclipse.basyx.examples.snippets.AbstractSnippetTest;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.junit.Test;
+
+/**
+ * Test for the CreateAAS snippet
+ * 
+ * @author conradi
+ *
+ */
+public class TestCreateAAS extends AbstractSnippetTest {
+
+	private static final String AAS_ID_SHORT = "aasIdShort";
+	private static final String AAS_ID = "aasId";
+	
+	private static final String ASSET_ID_SHORT = "assetIdShort";
+	private static final String ASSET_ID = "assetId";
+	
+	
+	@Test
+	public void testCreateAAS() {
+		
+		// Create an example Asset to be used in the AAS
+		Asset asset = new Asset(ASSET_ID_SHORT, new Identifier(IdentifierType.CUSTOM, ASSET_ID), AssetKind.INSTANCE);
+		
+		// Create an AAS
+		AssetAdministrationShell aas = CreateAAS.createAAS(AAS_ID_SHORT, new Identifier(IdentifierType.CUSTOM, AAS_ID), asset);
+		
+		// Check the created AAS
+		assertEquals(AAS_ID_SHORT, aas.getIdShort());
+		assertEquals(AAS_ID, aas.getIdentification().getId());
+		assertEquals(ASSET_ID_SHORT, aas.getAsset().getIdShort());
+		assertEquals(ASSET_ID, aas.getAsset().getIdentification().getId());
+	}
+	
+}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/TestDeleteSubmodelFromAAS.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/TestDeleteSubmodelFromAAS.java
new file mode 100644
index 0000000..3da923c
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/TestDeleteSubmodelFromAAS.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.aas;
+
+import static org.junit.Assert.fail;
+
+import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
+import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
+import org.eclipse.basyx.examples.snippets.AbstractSnippetTest;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.junit.Test;
+
+/**
+ * Test for the DeleteSubmodelFromAAS snippet
+ * 
+ * @author conradi
+ *
+ */
+public class TestDeleteSubmodelFromAAS extends AbstractSnippetTest {
+
+	@Test
+	public void testDeleteSubmodel() {
+		
+		// Get the Identifier of the example AAS and Submodel
+		IIdentifier aasIdentifier = new Identifier(IdentifierType.CUSTOM, AAS_ID);
+		IIdentifier smIdentifier = new Identifier(IdentifierType.CUSTOM, SM_ID);
+		
+		// Get the AAS as ConnectedAAS
+		ConnectedAssetAdministrationShellManager manager = getManager();
+		IAssetAdministrationShell aas = manager.retrieveAAS(aasIdentifier);
+		
+		DeleteSubmodelFromAAS.deleteSubmodelFromAAS(smIdentifier, aas);
+		
+		// Try to retrieve deleted Submodel; should throw ResourceNotFoundException
+		try {
+			aas.getSubmodel(smIdentifier);
+			fail();
+		} catch (ResourceNotFoundException e) {
+		}
+		
+	}
+	
+}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/TestRetrieveSubmodelFromAAS.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/TestRetrieveSubmodelFromAAS.java
new file mode 100644
index 0000000..0cd2cc2
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/TestRetrieveSubmodelFromAAS.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.aas;
+
+import static org.junit.Assert.assertEquals;
+
+import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
+import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
+import org.eclipse.basyx.examples.snippets.AbstractSnippetTest;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.junit.Test;
+
+/**
+ * Test for the RetrieveSubmodelFromAAS snippet
+ * 
+ * @author conradi
+ *
+ */
+public class TestRetrieveSubmodelFromAAS extends AbstractSnippetTest {
+
+	
+	@Test
+	public void testRetrieveSubmodelFromAAS() {
+		// Get the Identifiers for the AAS and the Submodel
+		IIdentifier aasIdentifier = new Identifier(IdentifierType.CUSTOM, AAS_ID);
+		IIdentifier smIdentifier = new Identifier(IdentifierType.CUSTOM, SM_ID);
+		
+		// Get the AAS as ConnectedAAS
+		ConnectedAssetAdministrationShellManager manager = getManager();
+		IAssetAdministrationShell aas = manager.retrieveAAS(aasIdentifier);
+		
+		// Get the Submodel from the server
+		ISubmodel remoteSubmodel = RetrieveSubmodelFromAAS.retrieveSubmodelFromAAS(
+				smIdentifier, aas);
+		
+		
+		// Check if the Submodel can be used correctly
+		assertEquals(SM_ID_SHORT, remoteSubmodel.getIdShort());
+	}
+	
+}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/active/RunComposedActiveModelSnippet.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/active/RunComposedActiveModelSnippet.java
index 7504981..410f492 100644
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/active/RunComposedActiveModelSnippet.java
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/active/RunComposedActiveModelSnippet.java
@@ -1,8 +1,17 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.examples.snippets.aas.active;
 
 import org.eclipse.basyx.examples.snippets.aas.active.tasks.AverageTask;
 import org.eclipse.basyx.examples.snippets.aas.active.tasks.IncrementTask;
-import org.eclipse.basyx.submodel.restapi.SubModelProvider;
+import org.eclipse.basyx.submodel.restapi.SubmodelProvider;
 import org.eclipse.basyx.tools.aas.active.ActiveModel;
 import org.eclipse.basyx.tools.aas.active.VABModelTaskGroup;
 import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
@@ -26,7 +35,7 @@
 	@Ignore
 	public void snippet() throws Exception {
 		// Create the model provider for the active model
-		IModelProvider modelProvider = new SubModelProvider();
+		IModelProvider modelProvider = new SubmodelProvider();
 		modelProvider.createValue("count", 0);
 		modelProvider.createValue("temperature", VABLambdaProviderHelper.createSimple(() -> {
 			return 30d + (Math.random() * 10d - 5d);
@@ -46,8 +55,8 @@
 
 		// Runs a task group with a single task (1x per second)
 		VABModelTaskGroup printerGroup = activeModel.runTask(1000, model -> {
-			logger.debug("Current count: " + model.getModelPropertyValue("/count"));
-			logger.debug("Current average: " + model.getModelPropertyValue("/average"));
+			logger.debug("Current count: " + model.getValue("/count"));
+			logger.debug("Current average: " + model.getValue("/average"));
 		});
 
 		// Adds an additional task to the existing task group
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/active/RunInfluxDBActiveModelSnippet.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/active/RunInfluxDBActiveModelSnippet.java
index e6ec3db..129f058 100644
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/active/RunInfluxDBActiveModelSnippet.java
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/active/RunInfluxDBActiveModelSnippet.java
@@ -1,7 +1,16 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.examples.snippets.aas.active;
 
 import org.eclipse.basyx.examples.snippets.aas.active.tasks.InfluxDBTask;
-import org.eclipse.basyx.submodel.restapi.SubModelProvider;
+import org.eclipse.basyx.submodel.restapi.SubmodelProvider;
 import org.eclipse.basyx.tools.aas.active.ActiveModel;
 import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
 import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaProviderHelper;
@@ -28,7 +37,7 @@
 	@Test
 	public void snippet() throws Exception {
 		// Create the model provider for the active model
-		IModelProvider modelProvider = new SubModelProvider();
+		IModelProvider modelProvider = new SubmodelProvider();
 		modelProvider.createValue("temperature", VABLambdaProviderHelper.createSimple(() -> {
 			return 30d + (Math.random() * 10d - 5d);
 		}, null));
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/active/tasks/AverageTask.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/active/tasks/AverageTask.java
index b4f710e..9e5fd95 100644
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/active/tasks/AverageTask.java
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/active/tasks/AverageTask.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.examples.snippets.aas.active.tasks;
 
 import org.eclipse.basyx.tools.aas.active.VABModelTask;
@@ -23,14 +32,14 @@
 
 	@Override
 	public void execute(IModelProvider model) throws Exception {
-		double nextValue = (double) model.getModelPropertyValue(sourcePath);
+		double nextValue = (double) model.getValue(sourcePath);
 		double average = lastAverage;
 		if ( average == 0 ) {
 			average = nextValue;
 		} else {
 			average = average * (1 - factor) + nextValue * factor;
 		}
-		model.setModelPropertyValue(targetPath, average);
+		model.setValue(targetPath, average);
 		lastAverage = average;
 	}
 }
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/active/tasks/IncrementTask.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/active/tasks/IncrementTask.java
index ead95e7..8850659 100644
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/active/tasks/IncrementTask.java
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/active/tasks/IncrementTask.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.examples.snippets.aas.active.tasks;
 
 import org.eclipse.basyx.tools.aas.active.VABModelTask;
@@ -18,7 +27,7 @@
 
 	@Override
 	public void execute(IModelProvider model) throws Exception {
-		int current = (int) model.getModelPropertyValue(path);
-		model.setModelPropertyValue(path, current + 1);
+		int current = (int) model.getValue(path);
+		model.setValue(path, current + 1);
 	}
 }
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/active/tasks/InfluxDBTask.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/active/tasks/InfluxDBTask.java
index 6e0c402..fb118b2 100644
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/active/tasks/InfluxDBTask.java
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/active/tasks/InfluxDBTask.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.examples.snippets.aas.active.tasks;
 
 import java.io.IOException;
@@ -39,7 +48,7 @@
 	@Override
 	public void execute(IModelProvider model) throws Exception {
 		try {
-			Object value = model.getModelPropertyValue(modelPath);
+			Object value = model.getValue(modelPath);
 			String result = value == null ? "null" : value.toString();
 			writeData(result);
 		} catch (Exception e) {
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/deployment/device/DeviceAASDeployment.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/deployment/device/DeviceAASDeployment.java
deleted file mode 100644
index e5a4db2..0000000
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/deployment/device/DeviceAASDeployment.java
+++ /dev/null
@@ -1,74 +0,0 @@
-package org.eclipse.basyx.examples.snippets.aas.deployment.device;
-
-import static org.junit.Assert.assertTrue;
-
-import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
-import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
-import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
-import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
-import org.eclipse.basyx.aas.restapi.AASModelProvider;
-import org.eclipse.basyx.aas.restapi.VABMultiSubmodelProvider;
-import org.eclipse.basyx.examples.support.directory.ExampleAASRegistry;
-import org.eclipse.basyx.vab.protocol.basyx.connector.BaSyxConnectorProvider;
-import org.eclipse.basyx.vab.protocol.basyx.server.BaSyxTCPServer;
-import org.junit.Test;
-
-/**
- * Code snippet that illustrates the deployment of an AAS to a device, and connects to that AAS
- * 
- * The AAS is deployed to a dynamic BaSyxTCPServer that exports the AAS using the BaSyx TCP protocol.
- * 
- * @author kuhn
- *
- */
-public class DeviceAASDeployment {
-
-	
-	/**
-	 * Run code snippet. Connect to AAS on server, access AAS properties. 
-	 */
-	@Test
-	public void createExportAndAccessSubModel() throws Exception {
-
-
-		// Create AAS sub model and sub model properties
-		// - Create AAS
-		AssetAdministrationShell aas = new AssetAdministrationShell();
-		// - Set sub model ID
-		aas.setIdShort("urn:de.FHG:devices.es.iese:AAS:1.0:3:x-509#003");
-
-
-		// Export AAS via BaSyx server
-		AASModelProvider modelProvider = new AASModelProvider(aas);
-		VABMultiSubmodelProvider aasProvider = new VABMultiSubmodelProvider(modelProvider);
-		BaSyxTCPServer<VABMultiSubmodelProvider> server = new BaSyxTCPServer<VABMultiSubmodelProvider>(aasProvider, 9998);
-		// - Start local BaSyx/TCP server
-		server.start();
-
-
-
-		// - We pre-register the aas endpoints to the dynamic BaSyx server
-		ExampleAASRegistry registry = new ExampleAASRegistry();
-		registry.addAASMapping("dynamicAAS", "basyx://localhost:9998/aas");
-
-		// Create connected aas manager to connect with the dynamic server
-		ConnectedAssetAdministrationShellManager manager = new ConnectedAssetAdministrationShellManager(registry,
-				// We connect via BaSyx TCP protocol
-				new BaSyxConnectorProvider());
-
-		
-		// Retrieve the AAS with ID "dynamicAAS" from the AAS server with SDK connector
-		// - IAssetAdministrationShell is the interface for the local AAS proxy
-		IAssetAdministrationShell shell = manager.retrieveAAS(new ModelUrn("dynamicAAS"));
-		// - Retrieve AAS values and compare to expected values
-		Object propertyId = shell.getIdShort();
-
-		
-		// Check value
-		assertTrue(propertyId.equals("urn:de.FHG:devices.es.iese:AAS:1.0:3:x-509#003"));
-		
-	
-		// Stop local BaSyx/TCP server
-		server.stop();
-	}
-}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/deployment/device/DeviceAASDeploymentVAB.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/deployment/device/DeviceAASDeploymentVAB.java
deleted file mode 100644
index a8783db..0000000
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/deployment/device/DeviceAASDeploymentVAB.java
+++ /dev/null
@@ -1,65 +0,0 @@
-package org.eclipse.basyx.examples.snippets.aas.deployment.device;
-
-import static org.junit.Assert.assertTrue;
-
-import java.util.Map;
-
-import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
-import org.eclipse.basyx.aas.restapi.AASModelProvider;
-import org.eclipse.basyx.aas.restapi.VABMultiSubmodelProvider;
-import org.eclipse.basyx.vab.coder.json.connector.JSONConnector;
-import org.eclipse.basyx.vab.protocol.basyx.connector.BaSyxConnector;
-import org.eclipse.basyx.vab.protocol.basyx.server.BaSyxTCPServer;
-import org.junit.Test;
-
-/**
- * Code snippet that illustrates the deployment of an AAS to a device, and connects to that AAS
- * 
- * The AAS is deployed to a dynamic BaSyxTCPServer that exports the AAS using the BaSyx TCP protocol.
- * 
- * @author kuhn
- *
- */
-public class DeviceAASDeploymentVAB {
-
-	
-	/**
-	 * Run code snippet. Connect to AAS on server, access AAS properties. 
-	 */
-	@SuppressWarnings("unchecked")
-	@Test
-	public void createExportAndAccessSubModel() throws Exception {
-
-
-		// Create AAS sub model and sub model properties
-		// - Create AAS
-		AssetAdministrationShell aas = new AssetAdministrationShell();
-		// - Set sub model ID
-		aas.setIdShort("urn:de.FHG:devices.es.iese:AAS:1.0:3:x-509#003");
-
-
-		// Export AAS via BaSyx server
-		AASModelProvider modelProvider = new AASModelProvider(aas);
-		VABMultiSubmodelProvider aasProvider = new VABMultiSubmodelProvider(modelProvider);
-		BaSyxTCPServer<VABMultiSubmodelProvider> server = new BaSyxTCPServer<VABMultiSubmodelProvider>(aasProvider, 9998);
-		// - Start local BaSyx/TCP server
-		server.start();
-		
-		
-		// Access BaSyx TCP server using Virtual Automation Bus low level BaSyxConnector class
-		// - Create BaSyx connector to connect with the sub model
-		BaSyxConnector basyxConnector = new BaSyxConnector("localhost", 9998);
-		// - Create connection to BaSyx server manager
-		JSONConnector toDeviceManager = new JSONConnector(basyxConnector);	
-		// - Access sub model property, check value
-		AssetAdministrationShell shell = AssetAdministrationShell.createAsFacade((Map<String, Object>) toDeviceManager.getModelPropertyValue("aas"));
-
-		
-		// Check value
-		assertTrue(shell.getIdShort().equals("urn:de.FHG:devices.es.iese:AAS:1.0:3:x-509#003"));
-		
-	
-		// Stop local BaSyx/TCP server
-		server.stop();
-	}
-}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/deployment/device/DeviceSubModelDeployment.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/deployment/device/DeviceSubModelDeployment.java
deleted file mode 100644
index 8dcc0b5..0000000
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/deployment/device/DeviceSubModelDeployment.java
+++ /dev/null
@@ -1,97 +0,0 @@
-package org.eclipse.basyx.examples.snippets.aas.deployment.device;
-
-import static org.junit.Assert.assertTrue;
-
-import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
-import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
-import org.eclipse.basyx.aas.restapi.VABMultiSubmodelProvider;
-import org.eclipse.basyx.examples.support.directory.ExampleAASRegistry;
-import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
-import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
-import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.submodel.restapi.SubModelProvider;
-import org.eclipse.basyx.vab.protocol.basyx.connector.BaSyxConnectorProvider;
-import org.eclipse.basyx.vab.protocol.basyx.server.BaSyxTCPServer;
-import org.junit.Test;
-
-/**
- * Code snippet that illustrates the deployment of a AAS sub model to a device, and connects to that sub model
- * 
- * The AAS sub model is deployed to a dynamic BaSyxTCPServer that exports the sub model using the BaSyx TCP protocol.
- * 
- * @author kuhn
- *
- */
-public class DeviceSubModelDeployment {
-
-	
-	/**
-	 * Run code snippet. Connect to AAS sub model on server, access sub model properties. 
-	 */
-	@Test
-	public void createExportAndAccessSubModel() throws Exception {
-
-		
-		// Create AAS sub model and sub model properties
-
-		// - Create sub model
-		SubModel submodel = new SubModel();
-		// - Set sub model ID "SampleSM" to full qualified ID urn:de.FHG:devices.es.iese:SampleSM:1.0:3:x-509#003
-		IIdentifier smId = new ModelUrn("urn:de.FHG:devices.es.iese:SampleSM:1.0:3:x-509#003");
-		submodel.setIdShort("SampleSM");
-		submodel.setIdentification(smId.getIdType(), smId.getId());
-		// - Add example properties
-		Property prop1 = new Property(7);
-		prop1.setIdShort("prop1");
-		submodel.addSubModelElement(prop1);
-
-		Property prop2 = new Property("myStr");
-		prop2.setIdShort("prop2");
-		submodel.addSubModelElement(prop2);
-
-		
-		// Export sub model via BaSyx server
-		SubModelProvider modelProvider = new SubModelProvider(submodel);
-		VABMultiSubmodelProvider aasProvider = new VABMultiSubmodelProvider("SampleSM", modelProvider);
-		BaSyxTCPServer<VABMultiSubmodelProvider> server = new BaSyxTCPServer<>(aasProvider, 9998);
-		// - Start local BaSyx/TCP server
-		server.start();
-		
-		
-		// Create connected aas manager to connect with the dynamic server
-		// We pre-register the aas endpoints to the dynamic BaSyx server
-		ExampleAASRegistry registry = new ExampleAASRegistry();
-		registry.addAASMapping("", ""); // No AAS is provided in this example
-		registry.addSubmodelMapping("", smId.getId(), "basyx://localhost:9998/aas/submodels/SampleSM");
-		
-		// Create manager using the directory stub an the HTTPConnectorProvider
-		ConnectedAssetAdministrationShellManager manager = new ConnectedAssetAdministrationShellManager(registry,
-				// We connect via BaSyx TCP protocol
-				new BaSyxConnectorProvider());
-		
-		// Create and connect SDK connector
-		// - Retrieve sub model
-		ISubModel subModel = manager.retrieveSubModel(new ModelUrn(""), smId);
-		
-		// Retrieve sub model values and compare to expected values
-		String submodelId = subModel.getIdShort();
-		String prop1Id    = subModel.getProperties().get("prop1").getIdShort();
-		int prop1Val = (int) ((IProperty) subModel.getProperties().get("prop1")).get();
-		String prop2Id    = subModel.getProperties().get("prop2").getIdShort();
-		String prop2Val = (String) ((IProperty) subModel.getProperties().get("prop2")).get();
-
-		
-		// Compare received property values to expected values
-		assertTrue(submodelId.equals("SampleSM"));
-		assertTrue(prop1Id.equals("prop1"));
-		assertTrue(prop1Val == 7);
-		assertTrue(prop2Id.equals("prop2"));
-		assertTrue(prop2Val.equals("myStr"));
-
-	
-		// Stop local BaSyx/TCP server
-		server.stop();
-	}
-}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/deployment/device/DeviceSubModelDeploymentVAB.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/deployment/device/DeviceSubModelDeploymentVAB.java
deleted file mode 100644
index be00057..0000000
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/deployment/device/DeviceSubModelDeploymentVAB.java
+++ /dev/null
@@ -1,77 +0,0 @@
-package org.eclipse.basyx.examples.snippets.aas.deployment.device;
-
-import static org.junit.Assert.assertTrue;
-
-import java.util.HashMap;
-
-import org.eclipse.basyx.aas.restapi.VABMultiSubmodelProvider;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.submodel.restapi.SubModelProvider;
-import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
-import org.eclipse.basyx.vab.coder.json.connector.JSONConnector;
-import org.eclipse.basyx.vab.protocol.basyx.connector.BaSyxConnector;
-import org.eclipse.basyx.vab.protocol.basyx.server.BaSyxTCPServer;
-import org.junit.Test;
-
-/**
- * Code snippet that illustrates the deployment of a AAS sub model to a device, and connects to that sub model using
- * Virtual Automation Bus (VAB) primitives.
- * 
- * The AAS sub model is deployed to a dynamic BaSyxTCPServer that exports the sub model using the BaSyx TCP protocol.
- * 
- * @author kuhn
- *
- */
-public class DeviceSubModelDeploymentVAB {
-
-	
-	/**
-	 * Run code snippet. Connect to AAS sub model on server, access sub model properties using VAB properties. 
-	 */
-	@SuppressWarnings("unchecked")
-	@Test
-	public void createExportAndAccessSubModel() throws Exception {
-
-		
-		// Create AAS sub model and sub model properties
-		// - Create sub model
-		SubModel submodel = new SubModel();
-		// - Set sub model ID
-		submodel.setIdShort("dynamicSM");
-		// - Add example properties
-		Property prop1 = new Property(7);
-		prop1.setIdShort("prop1");
-		submodel.addSubModelElement(prop1);
-
-		Property prop2 = new Property("myStr");
-		prop2.setIdShort("prop2");
-		submodel.addSubModelElement(prop2);
-
-		
-		// Export sub model via BaSyx server
-		SubModelProvider modelProvider = new SubModelProvider(submodel);
-		VABMultiSubmodelProvider aasProvider = new VABMultiSubmodelProvider("dynamicSM", modelProvider);
-		BaSyxTCPServer<VABMultiSubmodelProvider> server = new BaSyxTCPServer<VABMultiSubmodelProvider>(aasProvider, 9998);
-		// - Start local BaSyx/TCP server
-		server.start();
-				
-		
-		// Access BaSyx TCP server using low-level BaSyx connector instead of connection manager
-		// - Create BaSyx connector to connect with the sub model
-		BaSyxConnector basyxConnector = new BaSyxConnector("localhost", 9998);
-		// - Create connection to BaSyx server manager
-		JSONConnector toDeviceManager = new JSONConnector(basyxConnector);	
-		// - Access sub model property, check value
-		int propVal = (int) ((HashMap<String, Object>) toDeviceManager
-				.getModelPropertyValue("/aas/submodels/dynamicSM/" + SubmodelElementProvider.PROPERTIES + "/prop1/value")).get("value");
-		
-		
-		// Check value
-		assertTrue(propVal == 7);
-		
-	
-		// Stop local BaSyx/TCP server
-		server.stop();
-	}
-}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/deployment/http/ConnectToRemoteAAS.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/deployment/http/ConnectToRemoteAAS.java
deleted file mode 100644
index 04219cc..0000000
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/deployment/http/ConnectToRemoteAAS.java
+++ /dev/null
@@ -1,94 +0,0 @@
-package org.eclipse.basyx.examples.snippets.aas.deployment.http;
-
-import static org.junit.Assert.assertTrue;
-
-import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
-import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
-import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
-import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
-import org.eclipse.basyx.components.servlet.aas.AASServlet;
-import org.eclipse.basyx.examples.contexts.BaSyxExamplesContext_Empty;
-import org.eclipse.basyx.examples.deployment.BaSyxDeployment;
-import org.eclipse.basyx.examples.support.directory.ExampleAASRegistry;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
-import org.junit.ClassRule;
-import org.junit.Test;
-
-/**
- * Code snippet that illustrates the creation of an Asset Administration Shell (AAS) by extending an SDK class
- * 
- * The AAS is deployed to an AASServlet instance running on a Apache Tomcat HTTP server. The AASServlet exports
- * an Asset Administration Shell via the defined BaSyx REST interface. 
- * 
- * @author kuhn
- *
- */
-public class ConnectToRemoteAAS {
-
-	
-	/**
-	 * Example Asset Administration Shell
-	 */
-	static class ExampleAssetAdministrationShell extends AssetAdministrationShell {
-		/**
-		 * Constructor
-		 */
-		public ExampleAssetAdministrationShell() {
-			// Set Asset Administration Shell ID
-			setIdShort("aas-001");
-		}
-	}
-
-	
-	
-	/**
-	 * The BaSyx Deployment instantiates and starts context elements for this example. 
-	 * 
-	 * This example instantiates the BaSyxExamplesContext_1MemoryAASServer_1SQLDirectory
-	 * example context that creates one AAS server, and one SQL based AAS registry.
-	 * 
-	 * BaSyxDeployment contexts instantiate all components on the IP address of the host. 
-	 * Therefore, all components use the same IP address. 
-	 */
-	@ClassRule
-	public static BaSyxDeployment context = new BaSyxDeployment(
-				// Servlets for example snippet
-				new BaSyxExamplesContext_Empty().
-					// Deploy example specific servlets to Tomcat server in this context
-					addServletMapping("/Testsuite/components/BaSys/1.0/SampleAAS/*",         new AASServlet(new ExampleAssetAdministrationShell()))
-			);
-
-	
-	
-	/**
-	 * Run code snippet. Connect to AAS on server, access AAS properties. 
-	 */
-	@Test
-	public void connectToAAS() throws Exception {
-		// Create AAS Registry to store meta-infomation using aas descriptor
-		// This is a pre-configured aas registry that resolves urn to aas-descriptor
-		ExampleAASRegistry registry = new ExampleAASRegistry();
-		registry.addAASMapping("aas-001",
-				"http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/SampleAAS/aas");
-
-		// Create manager using the directory stub an the HTTPConnectorProvider
-		// - Connect to VAB object by ID. The connection manager looks up this ID in
-		//   its directory
-		ConnectedAssetAdministrationShellManager manager = new ConnectedAssetAdministrationShellManager(registry,
-				// We connect via HTTP
-				new HTTPConnectorProvider());
-		
-		// Retrieve the AAS from the AAS server with SDK connector
-		// - IAssetAdministrationShell is the interface for the local AAS proxy
-		IAssetAdministrationShell shell = manager
-				.retrieveAAS(new ModelUrn("aas-001"));
-		// - Retrieve AAS values and compare to expected values
-		Object propertyId = shell.getIdShort();
-		
-		
-		// Check result
-		assertTrue(propertyId.equals("aas-001"));
-	}
-}
-
-
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/registry/ConnectToAASEndpoints.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/registry/ConnectToAASEndpoints.java
deleted file mode 100644
index 3abd01b..0000000
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/registry/ConnectToAASEndpoints.java
+++ /dev/null
@@ -1,97 +0,0 @@
-package org.eclipse.basyx.examples.snippets.aas.registry;
-
-import static org.junit.Assert.assertEquals;
-
-import org.basyx.components.AASServer.servlet.AASServerServlet;
-import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
-import org.eclipse.basyx.aas.metamodel.connected.ConnectedAssetAdministrationShell;
-import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
-import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
-import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
-import org.eclipse.basyx.examples.TestContext;
-import org.eclipse.basyx.examples.deployment.BaSyxDeployment;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
-import org.junit.ClassRule;
-import org.junit.Test;
-
-/**
- * Code snippet that registers an AAS descriptor with the AAS registry and connects to the registered AAS endpoint
- * 
- * The snippet communicates with a VAB element that is deployed to a VABLambdaServlet on a
- * Apache Tomcat HTTP server instance. The VABLambdaServlet provides an empty container that
- * is able to host any VAB object.
- * 
- * @author kuhn
- *
- */
-public class ConnectToAASEndpoints {
-
-	
-	/**
-	 * Create VAB connection manager backend
-	 * 
-	 * The connection manager uses a preconfigured directory for resolving IDs to 
-	 * network addresses, and a HTTP connector to connect to VAB objects.
-	 */
-	protected ConnectedAssetAdministrationShellManager connManager = new ConnectedAssetAdministrationShellManager(
-			new AASRegistryProxy("http://localhost:8080/basys.examples/Components/Directory/SQL"),
-			new HTTPConnectorProvider());
-
-	
-	/**
-	 * The BaSyx Deployment instantiates and starts context elements for this example. 
-	 * 
-	 * This example instantiates the BaSyxExamplesContext_1MemoryAASServer_1SQLDirectory
-	 * example context that creates one AAS server, and one SQL based AAS registry.
-	 * 
-	 * BaSyxDeployment contexts instantiate all components on the IP address of the host. 
-	 * Therefore, all components use the same IP address. 
-	 */
-	@ClassRule
-	public static BaSyxDeployment context = new BaSyxDeployment(
-				// Simulated servlets
-				// - BaSys topology with one AAS Server and one SQL directory
-				TestContext.sqlContext.
-					// Deploy example specific servlets to Tomcat server in this context
-					addServletMapping("/Components/BaSys/1.0/aasServer/*", new AASServerServlet())
-			);
-
-	
-	
-	
-	/**
-	 * Run code snippet. This code snippet illustrates the creation of an AASDescriptor, the dynamic creation and deployment of AAS, 
-	 * the lookup of the AAS, and the access of the AAS. 
-	 */
-	@Test
-	public void snippet() throws Exception {
-		
-		// Create AAS descriptor and sub model descriptors
-		ModelUrn      aasURN         = new ModelUrn("urn:de.FHG:devices.es.iese:aas:1.0:3:x-509#001");
-		String aasSrvURL = "http://localhost:8080/basys.examples/Components/BaSys/1.0/aasServer";
-
-		// Create AAS
-		AssetAdministrationShell aas = new AssetAdministrationShell();
-
-		// - Set AAS ID
-		aas.setIdentification(aasURN);
-
-		// - Transfer AAS to server
-		//   - This creates the "urn:de.FHG:devices.es.iese:aas:1.0:3:x-509#001" element on the server, which is the server
-		//     end point that will host the AAS.
-		connManager.createAAS(aas, aasURN, aasSrvURL);
-
-		// Server connections
-		// - Connect AAS
-		ConnectedAssetAdministrationShell shell = connManager.retrieveAAS(aasURN);
-
-		// Retrieve the AAS from the AAS server with SDK connector
-		// - IAssetAdministrationShell is the interface for the local AAS proxy
-		// - Retrieve AAS values and compare to expected values
-		Object aasIDProperty = shell.getIdentification().getId();
-		
-		// Check property value
-		assertEquals(aasURN.getURN(), aasIDProperty);
-	}
-}
-
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/registry/ConnectToSubModelEndpoints.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/registry/ConnectToSubModelEndpoints.java
deleted file mode 100644
index c0264a0..0000000
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/registry/ConnectToSubModelEndpoints.java
+++ /dev/null
@@ -1,139 +0,0 @@
-package org.eclipse.basyx.examples.snippets.aas.registry;
-
-import static org.junit.Assert.assertTrue;
-
-import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
-import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
-import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
-import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
-import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
-import org.eclipse.basyx.aas.registration.api.IAASRegistryService;
-import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
-import org.eclipse.basyx.components.servlet.aas.AASServlet;
-import org.eclipse.basyx.examples.TestContext;
-import org.eclipse.basyx.examples.deployment.BaSyxDeployment;
-import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
-import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
-import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
-import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
-import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.vab.modelprovider.VABPathTools;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
-import org.junit.ClassRule;
-import org.junit.Test;
-
-/**
- * Code snippet that registers an AAS descriptor with the AAS registry and connects to a sub model of
- * the registered AAS endpoint
- * 
- * The snippet communicates with a VAB element that is deployed to a VABLambdaServlet on a
- * Apache Tomcat HTTP server instance. The VABLambdaServlet provides an empty container that
- * is able to host any VAB object.
- * 
- * @author kuhn
- *
- */
-public class ConnectToSubModelEndpoints {
-	/**
-	 * Create VAB connection manager backend
-	 * 
-	 * The connection manager uses a preconfigured directory for resolving IDs to 
-	 * network addresses, and a HTTP connector to connect to VAB objects.
-	 */
-	protected ConnectedAssetAdministrationShellManager connManager = new ConnectedAssetAdministrationShellManager(
-			new AASRegistryProxy("http://localhost:8080/basys.examples/Components/Directory/SQL"),
-			new HTTPConnectorProvider());
-
-	
-	/**
-	 * The BaSyx Deployment instantiates and starts context elements for this example. 
-	 * 
-	 * This example instantiates the BaSyxExamplesContext_1MemoryAASServer_1SQLDirectory
-	 * example context that creates one AAS server, and one SQL based AAS registry.
-	 * 
-	 * BaSyxDeployment contexts instantiate all components on the IP address of the host. 
-	 * Therefore, all components use the same IP address. 
-	 */
-	@ClassRule
-	public static BaSyxDeployment context = new BaSyxDeployment(
-				// Simulated servlets
-				// - BaSys topology with one AAS Server and one SQL directory
-				TestContext.sqlContext.
-					// Deploy example specific servlets to Tomcat server in this context
-					addServletMapping("/Components/BaSys/1.0/aasServer/*",
-							new AASServlet(new AssetAdministrationShell()))
-			);
-
-	
-	
-	
-	/**
-	 * Run code snippet. This code snippet illustrates the creation of an AASDescriptor, the dynamic creation and deployment of an AAS sub model, 
-	 * the lookup of the AAS sub model, and the access of the AAS sub model. 
-	 */
-	@Test
-	public void snippet() throws Exception {
-		
-		// Create AAS descriptor and sub model descriptors
-		ModelUrn      aasURN         = new ModelUrn("urn:de.FHG:devices.es.iese:aas:1.0:3:x-509#001");
-		String        aasSrvURL      = "http://localhost:8080/basys.examples/Components/BaSys/1.0/aasServer/aas";
-		// - Sub model ID
-		String smIdShort = "exampleSM";
-		IIdentifier smId = new Identifier(IdentifierType.CUSTOM, "exampleSMId");
-		// - Create AAS descriptor and sub model descriptor
-		AASDescriptor aasDescriptor = new AASDescriptor(aasURN, aasSrvURL);
-		String smEndpoint = VABPathTools.concatenatePaths(aasSrvURL, "submodels", smIdShort);
-		SubmodelDescriptor submodelDescriptor = new SubmodelDescriptor(smIdShort, smId, smEndpoint);
-		// - Add sub model descriptor to AAS descriptor
-		aasDescriptor.addSubmodelDescriptor(submodelDescriptor);
-		
-
-		// Register AAS and sub model descriptors in directory (push AAS descriptor to server)
-		// - Connect to AAS registry
-		IAASRegistryService regProxy = new AASRegistryProxy(
-				"http://localhost:8080/basys.examples/Components/Directory/SQL");
-		// - Register AAS descriptor with AAS and sub model endpoints in registry
-		regProxy.register(aasDescriptor);
-		
-		// Create sub model
-		SubModel submodel = new SubModel();
-		submodel.setIdShort(smIdShort);
-		submodel.setIdentification(smId.getIdType(), smId.getId());
-
-		// - Add example properties to sub model
-		Property prop1 = new Property(7);
-		prop1.setIdShort("prop1");
-		submodel.addSubModelElement(prop1);
-
-		Property prop2 = new Property("myStr");
-		prop2.setIdShort("prop2");
-		submodel.addSubModelElement(prop2);
-		// - Transfer sub model to server
-		//   - This creates the "exampleSM" element on the server, which is the server
-		//     end point that will host the AAS sub model.
-		connManager.createSubModel(aasURN, submodel);
-
-	
-		// Connect to sub model using BaSyx SDK
-		ISubModel connSM = connManager.retrieveSubModel(aasURN, smId);
-
-		
-		// Read property values from sub model
-		String smID     = connSM.getIdShort();
-		String prop1Id = connSM.getProperties().get("prop1").getIdShort();
-		int prop1Val = (int) ((IProperty) connSM.getProperties().get("prop1")).get();
-		String prop2Id  = connSM.getProperties().get("prop2").getIdShort();
-		String prop2Val = (String) ((IProperty) connSM.getProperties().get("prop2")).get();
-
-		
-		// Check property values
-		assertTrue(smID.equals(smIdShort));
-		assertTrue(prop1Id.equals("prop1"));
-		assertTrue(prop1Val == 7);
-		assertTrue(prop2Id.equals("prop2"));
-		assertTrue(prop2Val.equals("myStr"));
-	}
-}
-
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/registry/RegisterRetrieveAASEndpoints.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/registry/RegisterRetrieveAASEndpoints.java
deleted file mode 100644
index ad842dd..0000000
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/registry/RegisterRetrieveAASEndpoints.java
+++ /dev/null
@@ -1,100 +0,0 @@
-package org.eclipse.basyx.examples.snippets.aas.registry;
-
-import static org.junit.Assert.assertTrue;
-
-import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
-import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
-import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
-import org.eclipse.basyx.aas.registration.api.IAASRegistryService;
-import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
-import org.eclipse.basyx.examples.TestContext;
-import org.eclipse.basyx.examples.deployment.BaSyxDeployment;
-import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
-import org.eclipse.basyx.vab.manager.VABConnectionManager;
-import org.eclipse.basyx.vab.modelprovider.VABPathTools;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
-import org.junit.ClassRule;
-import org.junit.Test;
-
-/**
- * Code snippet that registers an AAS descriptor with the AAS registry and accesses the registry using HTTP calls
- * 
- * The snippet communicates with a VAB element that is deployed to a VABLambdaServlet on a
- * Apache Tomcat HTTP server instance. The VABLambdaServlet provides an empty container that
- * is able to host any VAB object.
- * 
- * @author kuhn
- *
- */
-public class RegisterRetrieveAASEndpoints {
-
-	
-	/**
-	 * Create VAB connection manager backend
-	 * 
-	 * The connection manager uses a preconfigured directory for resolving IDs to 
-	 * network addresses, and a HTTP connector to connect to VAB objects.
-	 */
-	protected VABConnectionManager connManager = new VABConnectionManager(new ExamplesPreconfiguredDirectory(), new HTTPConnectorProvider());
-
-	
-	/**
-	 * The BaSyx Deployment instantiates and starts context elements for this example. 
-	 * 
-	 * This example instantiates the BaSyxExamplesContext_1MemoryAASServer_1SQLDirectory
-	 * example context that creates one AAS server, and one SQL based AAS registry.
-	 * 
-	 * BaSyxDeployment contexts instantiate all components on the IP address of the host. 
-	 * Therefore, all components use the same IP address. 
-	 */
-	@ClassRule
-	public static BaSyxDeployment context = new BaSyxDeployment(
-				// Simulated servlets
-				// - BaSys topology with one AAS Server and one SQL directory
-				TestContext.sqlContext
-			);
-
-	
-	
-	
-	/**
-	 * Run code snippet. This code snippet illustrates the creation of an AASDescriptor, its registration, and 
-	 * the lookup of the AAS using HTTP REST calls
-	 */
-	@Test
-	public void snippet() throws Exception {
-		
-		// Create AAS descriptor and sub model descriptors
-		ModelUrn      aasURN         = new ModelUrn("urn:de.FHG:devices.es.iese:aas:1.0:3:x-509#001");
-		ModelUrn      subModelURN    = new ModelUrn("urn:de.FHG:devices.es.iese:exampleSM:1.0:3:x-509#001");
-		String        aasSrvURL      = "http://localhost:8080/basys.examples/Components/BaSys/1.0/aasServer";
-		String        aasSrvPrefix   = "/aas/submodels/aasRepository/sampleAAS";
-		// - Create AAS descriptor
-		AASDescriptor aasDescriptor = new AASDescriptor(aasURN,
-				VABPathTools.concatenatePaths(aasSrvURL, aasSrvPrefix, aasURN.getEncodedURN()));
-		// - Add sub model descriptor URI
-		SubmodelDescriptor submodelDescriptor = new SubmodelDescriptor(subModelURN.getEncodedURN(), subModelURN, VABPathTools.concatenatePaths(aasSrvURL, aasSrvPrefix, subModelURN.getEncodedURN()));
-		aasDescriptor.addSubmodelDescriptor(submodelDescriptor);
-
-
-		// Register AAS and sub model descriptors in directory (push AAS descriptor to server)
-		// - Connect to AAS registry
-		IAASRegistryService regProxy = new AASRegistryProxy(
-				"http://localhost:8080/basys.examples/Components/Directory/SQL");
-		// - Register AAS descriptor with AAS and sub model endpoints in registry
-		regProxy.register(aasDescriptor);
-
-		
-		// Lookup AAS descriptor
-		AASDescriptor aasDesc = regProxy.lookupAAS(aasURN);
-		// - AAS end sub model end points
-		String aasEndpointURL = aasDesc.getFirstEndpoint();
-		String smEndpointURL  = aasDesc.getSubModelDescriptor(subModelURN).getFirstEndpoint();
-		
-		
-		// Check results
-		assertTrue(aasEndpointURL.equals("http://localhost:8080/basys.examples/Components/BaSys/1.0/aasServer/aas/submodels/aasRepository/sampleAAS/urn%3Ade.FHG%3Adevices.es.iese%3Aaas%3A1.0%3A3%3Ax-509%23001"));
-		assertTrue(smEndpointURL.equals("http://localhost:8080/basys.examples/Components/BaSys/1.0/aasServer/aas/submodels/aasRepository/sampleAAS/urn%3Ade.FHG%3Adevices.es.iese%3AexampleSM%3A1.0%3A3%3Ax-509%23001"));
-	}
-}
-
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/submodels/ConnectToAASSubModelSDK.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/submodels/ConnectToAASSubModelSDK.java
deleted file mode 100644
index a2f2681..0000000
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/submodels/ConnectToAASSubModelSDK.java
+++ /dev/null
@@ -1,137 +0,0 @@
-package org.eclipse.basyx.examples.snippets.aas.submodels;
-
-import static org.junit.Assert.assertEquals;
-
-import java.util.Map;
-
-import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
-import org.eclipse.basyx.components.servlet.submodel.SubmodelServlet;
-import org.eclipse.basyx.examples.contexts.BaSyxExamplesContext_Empty;
-import org.eclipse.basyx.examples.deployment.BaSyxDeployment;
-import org.eclipse.basyx.examples.support.directory.ExampleAASRegistry;
-import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
-import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
-import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
-import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
-import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElementCollection;
-import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
-import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
-import org.junit.ClassRule;
-import org.junit.Test;
-
-/**
- * Code snippet that illustrates the use of CRUD Virtual Automation Bus (VAB) operations
- * 
- * The snippet communicates with a VAB element that is deployed to a VABLambdaServlet on a
- * Apache Tomcat HTTP server instance. The VABLambdaServlet provides an empty container that
- * is able to host any VAB object.
- * 
- * @author kuhn
- *
- */
-public class ConnectToAASSubModelSDK {
-
-	
-	/**
-	 * Example sub model. This example sub model is created with the BaSyx SDK factory and defines the AAS meta model properties
-	 */
-	static class SampleSubModel extends SubModel {
-		/**
-		 * Constructor - create sub model
-		 * 
-		 * This sub model contains static properties, i.e. properties that have a static value assigned.
-		 */
-		@SuppressWarnings("unchecked")
-		public SampleSubModel() {
-			// Set sub model id and name
-			setIdShort("smName");
-			setIdentification(IdentifierType.CUSTOM, "sm-001");
-
-			// Add example properties
-			// - Add simple property
-			Property prop1 = new Property(234);
-			prop1.setIdShort("prop1");
-			addSubModelElement(prop1);
-
-			Property prop11 = new Property(123);
-			prop11.setIdShort("prop11");
-			// - Add container property that holds other properties
-			SubmodelElementCollection container = new SubmodelElementCollection();
-			container.setIdShort("prop2");
-			container.addElement(prop11);
-			// - Add container to property map
-			addSubModelElement(container);
-
-			// Add another property manually to sub model container "properties"
-			Property prop3 = new Property(17);
-			prop3.setIdShort("prop3");
-			((Map<String, Object>) this.get("submodelElements")).put("prop3", prop3);
-		}
-	}
-
-	
-	
-	/**
-	 * The BaSyx Deployment instantiates and starts context elements for this example. 
-	 * 
-	 * This example instantiates the BaSyxExamplesContext_1MemoryAASServer_1SQLDirectory
-	 * example context that creates one AAS server, and one SQL based AAS registry.
-	 * 
-	 * BaSyxDeployment contexts instantiate all components on the IP address of the host. 
-	 * Therefore, all components use the same IP address. 
-	 */
-	@ClassRule
-	public static BaSyxDeployment context = new BaSyxDeployment(
-				// Servlets for example snippet
-				new BaSyxExamplesContext_Empty().
-					// Deploy example specific servlets to Tomcat server in this context
-					addServletMapping("/Testsuite/components/BaSys/1.0/SampleModel/*",       new SubmodelServlet(new SampleSubModel()))
-			);
-
-	
-	/**
-	 * Run code snippet. Access sub model, query data
-	 */
-	@Test
-	public void accessSubModel() throws Exception {
-		// Create the AAS registry
-		ExampleAASRegistry registry = new ExampleAASRegistry();
-		registry.addAASMapping("aas-001", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/SampleModel/")
-			.addSubmodelMapping("aas-001", "sm-001", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/SampleModel/");
-		
-		// Create manager using the directory stub and the HTTPConnectorProvider
-		ConnectedAssetAdministrationShellManager manager = new ConnectedAssetAdministrationShellManager(registry,
-				// We connect via HTTP
-				new HTTPConnectorProvider());
-		
-		
-		// Retrieve sub model (created by factory) with SDK connector
-		// - Create and connect SDK connector
-		IIdentifier aasId = new Identifier(IdentifierType.CUSTOM, "aas-001");
-		IIdentifier smId = new Identifier(IdentifierType.CUSTOM, "sm-001");
-		ISubModel subModel = manager.retrieveSubModel(aasId, smId);
-
-		// - Retrieve sub model values and compare to expected values
-		Map<String, ISubmodelElement> smElements = subModel.getSubmodelElements();
-		IProperty prop1 = (IProperty) smElements.get("prop1");
-		ISubmodelElementCollection prop2 = (ISubmodelElementCollection) smElements.get("prop2");
-		IProperty prop11 = (IProperty) prop2.getProperties().get("prop11");
-		IProperty prop3 = (IProperty) smElements.get("prop3");
-
-		assertEquals(smId.getId(), subModel.getIdentification().getId());
-		assertEquals("smName", subModel.getIdShort());
-		assertEquals("prop1", prop1.getIdShort());
-		assertEquals(234, prop1.get());
-		assertEquals("prop2", prop2.getIdShort());
-		assertEquals("prop11", prop11.getIdShort());
-		assertEquals(123, prop11.get());
-		assertEquals("prop3", prop3.getIdShort());
-		assertEquals(17, prop3.get());
-	}
-}
-
-
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/submodels/ConnectToAASSubModelVAB.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/submodels/ConnectToAASSubModelVAB.java
deleted file mode 100644
index d48956b..0000000
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/submodels/ConnectToAASSubModelVAB.java
+++ /dev/null
@@ -1,161 +0,0 @@
-package org.eclipse.basyx.examples.snippets.aas.submodels;
-
-import static org.junit.Assert.assertEquals;
-
-import java.util.Map;
-
-import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
-import org.eclipse.basyx.components.servlet.submodel.SubmodelServlet;
-import org.eclipse.basyx.examples.contexts.BaSyxExamplesContext_Empty;
-import org.eclipse.basyx.examples.deployment.BaSyxDeployment;
-import org.eclipse.basyx.examples.support.directory.ExampleAASRegistry;
-import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
-import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
-import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
-import org.eclipse.basyx.submodel.metamodel.map.qualifier.Identifiable;
-import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
-import org.eclipse.basyx.vab.manager.VABConnectionManager;
-import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
-import org.junit.ClassRule;
-import org.junit.Test;
-
-
-
-/**
- * Code snippet that illustrates the use of CRUD Virtual Automation Bus (VAB) operations
- * 
- * The snippet communicates with a VAB element that is deployed to a VABLambdaServlet on a
- * Apache Tomcat HTTP server instance. The VABLambdaServlet provides an empty container that
- * is able to host any VAB object.
- * 
- * @author kuhn
- *
- */
-public class ConnectToAASSubModelVAB {
-
-	
-	/**
-	 * Example sub model. This example sub model is created with the BaSyx SDK factory and defines the AAS meta model properties
-	 */
-	static class SampleSubModel extends SubModel {
-		/**
-		 * Constructor - create sub model
-		 * 
-		 * This sub model contains static properties, i.e. properties that have a static value assigned.
-		 */
-		@SuppressWarnings("unchecked")
-		public SampleSubModel() {
-			// Set sub model id and name
-			setIdShort("smName");
-			setIdentification(IdentifierType.CUSTOM, "sm-001");
-
-			// Add example properties
-			// - Add simple property
-			Property prop1 = new Property(234);
-			prop1.setIdShort("prop1");
-			addSubModelElement(prop1);
-
-			Property prop11 = new Property(123);
-			prop11.setIdShort("prop11");
-			// - Add container property that holds other properties
-			SubmodelElementCollection container = new SubmodelElementCollection();
-			container.setIdShort("prop2");
-			container.addElement(prop11);
-			// - Add container to property map
-			addSubModelElement(container);
-
-			// Add another property manually to sub model container "properties"
-			Property prop3 = new Property(17);
-			prop3.setIdShort("prop3");
-			((Map<String, Object>) this.get("submodelElements")).put("prop3", prop3);
-		}
-	}
-
-	
-	
-	/**
-	 * Create VAB connection manager backend
-	 * 
-	 * The connection manager uses a preconfigured directory for resolving IDs to 
-	 * network addresses, and a HTTP connector to connect to VAB objects.
-	 */
-	protected VABConnectionManager connManager = new VABConnectionManager(
-			// Add example specific mappings
-			new ExamplesPreconfiguredDirectory()
-				.addMapping("aas-001",    "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/SampleModel/")
-			    .addMapping("sm-001",     "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/SampleModel/")
-			    .addMapping("sm-001VAB",  "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/SampleModel/"),
-			// We connect via HTTP
-			new HTTPConnectorProvider());
-
-	protected ConnectedAssetAdministrationShellManager manager = new ConnectedAssetAdministrationShellManager(
-			new ExampleAASRegistry()
-					.addAASMapping("aas-001", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/SampleModel/")
-					.addSubmodelMapping("aas-001", "sm-001", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/SampleModel/"),
-			// We connect via HTTP
-			new HTTPConnectorProvider());
-	
-	
-	/**
-	 * The BaSyx Deployment instantiates and starts context elements for this example. 
-	 * 
-	 * This example instantiates the BaSyxExamplesContext_1MemoryAASServer_1SQLDirectory
-	 * example context that creates one AAS server, and one SQL based AAS registry.
-	 * 
-	 * BaSyxDeployment contexts instantiate all components on the IP address of the host. 
-	 * Therefore, all components use the same IP address. 
-	 */
-	@ClassRule
-	public static BaSyxDeployment context = new BaSyxDeployment(
-				// Servlets for example snippet
-				new BaSyxExamplesContext_Empty().
-					// Deploy example specific servlets to Tomcat server in this context
-					addServletMapping("/Testsuite/components/BaSys/1.0/SampleModel/*",       new SubmodelServlet(new SampleSubModel()))
-			);
-
-	
-	/**
-	 * Run code snippet. Access sub model, query data
-	 */
-	@Test @SuppressWarnings("unchecked")
-	public void accessSubModel() throws Exception {
-		// Retrieve sub model (created by factory) with SDK connector
-		// - Connect to sub model using lower-level VAB interface
-		VABElementProxy connSubModel1 = this.connManager.connectToVABElement("sm-001VAB");
-		Map<String, Object> submodel = (Map<String, Object>) connSubModel1.getModelPropertyValue("");
-		Map<String, Object> smId = (Map<String, Object>) submodel.get(Identifiable.IDENTIFICATION);
-
-		// - Read properties
-		Map<String, Object> prop1 = (Map<String, Object>) connSubModel1.getModelPropertyValue(SubmodelElementProvider.PROPERTIES + "/prop1");
-		Map<String, Object> prop2 = (Map<String, Object>) connSubModel1.getModelPropertyValue(SubmodelElementProvider.PROPERTIES + "/prop2");
-		Map<String, Object> prop11 = (Map<String, Object>) connSubModel1.getModelPropertyValue("submodelElements/prop2/prop11");
-		Map<String, Object> prop3 = (Map<String, Object>) connSubModel1.getModelPropertyValue(SubmodelElementProvider.PROPERTIES + "/prop3");
-
-		// - Change property value using VAB primitive
-		connSubModel1.setModelPropertyValue(SubmodelElementProvider.PROPERTIES + "/prop1/value", 456);
-
-		// - Read value back using VAB primitive
-		Map<String, Object> changedProp1 = (Map<String, Object>) connSubModel1
-				.getModelPropertyValue(SubmodelElementProvider.PROPERTIES + "/prop1");
-
-		// - Check results
-		assertEquals("sm-001", smId.get(Identifier.ID));
-		assertEquals("smName", submodel.get(Referable.IDSHORT));
-		assertEquals("prop1", prop1.get(Referable.IDSHORT));
-		assertEquals(234, prop1.get(Property.VALUE)); // old value of prop1 has been stored locally
-		assertEquals(456, changedProp1.get(Property.VALUE)); // new value is 456
-		assertEquals("prop2", prop2.get(Referable.IDSHORT));
-		assertEquals("prop11", prop11.get(Referable.IDSHORT));
-		assertEquals(123, prop11.get(Property.VALUE));
-		assertEquals("prop3", prop3.get(Referable.IDSHORT));
-		assertEquals(17, prop3.get(Property.VALUE));
-
-	}
-}
-
-
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/submodels/CreateAASSubModelSDK.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/submodels/CreateAASSubModelSDK.java
deleted file mode 100644
index a349f50..0000000
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/submodels/CreateAASSubModelSDK.java
+++ /dev/null
@@ -1,78 +0,0 @@
-package org.eclipse.basyx.examples.snippets.aas.submodels;
-
-import static org.junit.Assert.assertTrue;
-
-import java.util.Map;
-
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.junit.Test;
-
-
-
-/**
- * Code snippet that illustrates the creation of an AAS sub model
- * 
- * @author kuhn
- *
- */
-public class CreateAASSubModelSDK {
-
-	
-	/**
-	 * Example sub model. This example sub model is created with the BaSyx SDK factory and defines the AAS meta model properties
-	 */
-	static class SampleSubModel extends SubModel {
-		/**
-		 * Constructor - create sub model
-		 * 
-		 * This sub model contains static properties, i.e. properties that have a static value assigned.
-		 */
-		@SuppressWarnings("unchecked")
-		public SampleSubModel() {
-			// Set sub model ID
-			setIdShort("sm-001");
-
-			// Add example properties
-			// - Add simple property
-			Property prop1 = new Property(234);
-			prop1.setIdShort("prop1");
-			addSubModelElement(prop1);
-
-			Property prop11 = new Property(123);
-			prop11.setIdShort("prop11");
-			// - Add container property that holds other properties
-			SubmodelElementCollection container = new SubmodelElementCollection();
-			container.setIdShort("prop2");
-			container.addElement(prop11);
-			// - Add container to property map
-			addSubModelElement(container);
-
-			// Add another property manually to sub model container "properties"
-			Property prop3 = new Property(17);
-			prop3.setIdShort("prop3");
-			{
-				((Map<String, Object>) this.get("submodelElements")).put("prop3", prop3);
-			}
-		}
-	}
-
-	
-	/**
-	 * Run code snippet. Instantiate AAS sub model.
-	 */
-	@Test
-	public void accessSubModel() throws Exception {
-		// Instantiate AAS sub model
-		SampleSubModel sampleSM = new SampleSubModel();
-		
-		// Access sub model property
-		int propertyVal = (int) sampleSM.getPath("submodelElements/prop1/value");
-		
-		// Check property value
-		assertTrue(propertyVal == 234);
-	}
-}
-
-
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/submodels/CreateAASSubModelVAB.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/submodels/CreateAASSubModelVAB.java
deleted file mode 100644
index 84327cd..0000000
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/submodels/CreateAASSubModelVAB.java
+++ /dev/null
@@ -1,77 +0,0 @@
-package org.eclipse.basyx.examples.snippets.aas.submodels;
-
-import static org.junit.Assert.assertTrue;
-
-import java.util.Map;
-
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetypedef.PropertyValueTypeDefHelper;
-import org.junit.Test;
-
-
-
-/**
- * Code snippet that illustrates the creation of an AAS sub model
- * 
- * @author kuhn
- *
- */
-public class CreateAASSubModelVAB {
-
-	
-	/**
-	 * Example sub model. This example sub model is created with the BaSyx SDK factory and defines the AAS meta model properties
-	 */
-	static class SampleSubModel extends SubModel {
-		/**
-		 * Constructor - create sub model property
-		 * 
-		 * This sub model contains static properties, i.e. properties that have a static value assigned.
-		 */
-		@SuppressWarnings("unchecked")
-		public SampleSubModel() {
-			// Set sub model ID
-			setIdShort("sm-001M");
-
-			// Add example properties
-			// - Add simple property with value and idShort meta elements
-			this.putPath("properties/prop1/value",     234);
-			this.putPath("properties/prop1/valueType", PropertyValueTypeDefHelper.getTypeWrapperFromObject(234));
-			this.putPath("properties/prop1/idShort",   "prop1");
-
-			// Add container property that holds other properties
-			this.putPath("properties/prop2/idShort", "prop2");
-			// - Add contained property
-			this.putPath("properties/prop2/properties/prop11/value",     123);
-			this.putPath("properties/prop2/properties/prop11/valueType", PropertyValueTypeDefHelper.getTypeWrapperFromObject(123).toString());
-			this.putPath("properties/prop2/properties/prop11/idShort", "prop11");
-			
-			// Add another property manually to sub model container "properties"
-			// - Using the Property class ensures presence of all meta properties
-			Property addedProperty = new Property(); 
-			addedProperty.set(17);
-			addedProperty.setIdShort("prop3");
-			// - Add property to sub model container "properties"
-			{((Map<String, Object>) this.get("properties")).put("prop3", addedProperty);}
-		}
-	}
-
-	
-	/**
-	 * Run code snippet. Instantiate AAS sub model.
-	 */
-	@Test
-	public void accessSubModel() throws Exception {
-		// Instantiate AAS sub model
-		SampleSubModel sampleSM = new SampleSubModel();
-		
-		// Access sub model property
-		int propertyVal = (int) sampleSM.getPath("properties/prop1/value");
-		
-		// Check property value
-		assertTrue(propertyVal == 234);
-	}
-}
-
-
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/submodels/DynamicSubModelDeployment.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/submodels/DynamicSubModelDeployment.java
deleted file mode 100644
index 2a57024..0000000
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/submodels/DynamicSubModelDeployment.java
+++ /dev/null
@@ -1,113 +0,0 @@
-package org.eclipse.basyx.examples.snippets.aas.submodels;
-
-import static org.junit.Assert.assertTrue;
-
-import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
-import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
-import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
-import org.eclipse.basyx.components.servlet.aas.AASServlet;
-import org.eclipse.basyx.examples.TestContext;
-import org.eclipse.basyx.examples.deployment.BaSyxDeployment;
-import org.eclipse.basyx.examples.support.directory.ExampleAASRegistry;
-import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
-import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
-import org.junit.ClassRule;
-import org.junit.Test;
-
-/**
- * Code snippet that illustrates the creation of an AAS sub model
- * 
- * @author kuhn
- *
- */
-public class DynamicSubModelDeployment {
-
-	private static final String AAS = "de.FHG:devices.es.iese:aas:1.0:3:x-509#003";
-	private static final String STATUS_SM = "de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003";
-
-	protected ConnectedAssetAdministrationShellManager aasManager = new ConnectedAssetAdministrationShellManager(
-			new ExampleAASRegistry()
-					.addAASMapping(AAS,
-							"http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/dynamicModelRepository/aas/")
-					// Ass Example specific mappings
-					.addSubmodelMapping(AAS, STATUS_SM,
-							"http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/dynamicModelRepository/aas/submodels/Status"),
-			new HTTPConnectorProvider());
-
-	/**
-	 * The BaSyx Deployment instantiates and starts context elements for this example. 
-	 * 
-	 * This example instantiates the BaSyxExamplesContext_1MemoryAASServer_1SQLDirectory
-	 * example context that creates one AAS server, and one SQL based AAS registry.
-	 * 
-	 * BaSyxDeployment contexts instantiate all components on the IP address of the host. 
-	 * Therefore, all components use the same IP address. 
-	 */
-	@ClassRule
-	public static BaSyxDeployment context = new BaSyxDeployment(
-				// Simulated servlets
-				// - BaSys topology with one AAS Server and one SQL directory
-				TestContext.sqlContext.
-					// Deploy example specific servlets to Apache Tomcat server in this context
-					addServletMapping("/Testsuite/components/BaSys/1.0/dynamicModelRepository/*",
-							new AASServlet(new AssetAdministrationShell()))
-			);
-
-	
-	
-	
-	/**
-	 * Run code snippet. This code snippet illustrates the use of CRUD operations to 
-	 * access Virtual Automation Bus objects
-	 */
-	@Test
-	public void snippet() throws Exception {
-		// Instantiate sub model
-		SubModel submodel = new SubModel();
-		// - Add example properties to sub model
-		submodel.setIdShort("Status");
-		Property prop1 = new Property(7);
-		prop1.setIdShort("prop1");
-		submodel.addSubModelElement(prop1);
-
-		Property prop2 = new Property("myStr");
-		prop2.setIdShort("prop2");
-		submodel.addSubModelElement(prop2);
-
-		
-		
-		// Transfer sub model to server
-		aasManager.createSubModel(new ModelUrn(AAS), submodel);
-
-		
-		// Retrieve sub model with SDK connector
-		{
-
-			// Server connections
-			// - Connect to sub model. Connecting to a sub model by its ID is discouraged, because a sub 
-			//   model ID is not necessarily unique outside the scope of its AAS. If users want to connect
-			//   directly to sub models, the registry needs to support this, and unique identifies (as here)
-			//   must be used. For portability, users should connect to sub models instead via an AAS ID and 
-			//   sub model ID tuple, as illustrated in the registry examples. 
-			ISubModel subModel = aasManager.retrieveSubModel(new ModelUrn(AAS), new ModelUrn(STATUS_SM));
-
-			// Read sub model properties
-			String smId     = subModel.getIdShort();
-			String prop1Id  = subModel.getProperties().get("prop1").getIdShort();
-			int prop1Val = (int) ((IProperty) subModel.getProperties().get("prop1")).get();
-			String prop2Id  = subModel.getProperties().get("prop2").getIdShort();
-			String prop2Val = (String) ((IProperty) subModel.getProperties().get("prop2")).get();
-			
-			// Compare sub model property values
-			assertTrue(smId.equals("Status"));
-			assertTrue(prop1Id.equals("prop1"));
-			assertTrue(prop1Val == 7);
-			assertTrue(prop2Id.equals("prop2"));
-			assertTrue(prop2Val.equals("myStr"));
-		}
-	}
-}
-
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/submodels/DynamicSubModelDeploymentHTTP.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/submodels/DynamicSubModelDeploymentHTTP.java
deleted file mode 100644
index 36b27c2..0000000
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/submodels/DynamicSubModelDeploymentHTTP.java
+++ /dev/null
@@ -1,117 +0,0 @@
-package org.eclipse.basyx.examples.snippets.aas.submodels;
-
-import static org.junit.Assert.assertTrue;
-
-import java.util.Map;
-
-import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
-import org.eclipse.basyx.components.servlet.aas.AASServlet;
-import org.eclipse.basyx.examples.TestContext;
-import org.eclipse.basyx.examples.deployment.BaSyxDeployment;
-import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
-import org.eclipse.basyx.tools.webserviceclient.WebServiceJSONClient;
-import org.eclipse.basyx.vab.manager.VABConnectionManager;
-import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
-import org.junit.ClassRule;
-import org.junit.Test;
-
-/**
- * Code snippet that illustrates the creation of an AAS sub model, and the access to the sub model via HTTP REST calls
- * 
- * @author kuhn
- *
- */
-public class DynamicSubModelDeploymentHTTP {
-
-	
-	/**
-	 * Create VAB connection manager backend
-	 * 
-	 * The connection manager uses a preconfigured directory for resolving IDs to 
-	 * network addresses, and a HTTP connector to connect to VAB objects.
-	 */
-	protected VABConnectionManager connManager = new VABConnectionManager(
-			new ExamplesPreconfiguredDirectory()
-				// Add example specific mappings
-					.addMapping("urn:de.FHG:devices.es.iese:aas:1.0:3:x-509:003",
-							"http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/dynamicModelRepository/aas"),
-			new HTTPConnectorProvider());
-
-	
-	/**
-	 * The BaSyx Deployment instantiates and starts context elements for this example. 
-	 * 
-	 * This example instantiates the BaSyxExamplesContext_1MemoryAASServer_1SQLDirectory
-	 * example context that creates one AAS server, and one SQL based AAS registry.
-	 * 
-	 * BaSyxDeployment contexts instantiate all components on the IP address of the host. 
-	 * Therefore, all components use the same IP address. 
-	 */
-	@ClassRule
-	public static BaSyxDeployment context = new BaSyxDeployment(
-				// Simulated servlets
-				// - BaSys topology with one AAS Server and one SQL directory
-				TestContext.sqlContext.
-					// Deploy example specific servlets to Apache Tomcat server in this context
-					addServletMapping("/Testsuite/components/BaSys/1.0/dynamicModelRepository/*",
-							new AASServlet(new AssetAdministrationShell()))
-			);
-
-	
-	
-	
-	/**
-	 * Run code snippet. This code snippet illustrates the dynamic deployment of a sub model and the use of HTTP REST operations to 
-	 * access the sub model
-	 */
-	@Test @SuppressWarnings("unchecked")
-	public void snippet() throws Exception {
-
-		// Server connections
-		// - Connect to sub model. Connecting to a sub model by its ID is discouraged, because a sub 
-		//   model ID is not necessarily unique outside the scope of its AAS. If users want to connect
-		//   directly to sub models, the registry needs to support this, and unique identifies (as here)
-		//   must be used. For portability, users should connect to sub models instead via an AAS ID and 
-		//   sub model ID tuple, as illustrated in the registry examples. 
-		VABElementProxy connSubModels = this.connManager.connectToVABElement("urn:de.FHG:devices.es.iese:aas:1.0:3:x-509:003");
-
-		// Add example properties
-		SubModel submodel = new SubModel();
-		submodel.setIdShort("Status");
-		Property prop1 = new Property(7);
-		prop1.setIdShort("prop1");
-		submodel.addSubModelElement(prop1);
-
-		Property prop2 = new Property("myStr");
-		prop2.setIdShort("prop2");
-		submodel.addSubModelElement(prop2);
-
-		// Transfer sub model to server
-		connSubModels.createValue("/submodels", submodel);
-
-		
-		// Web service client accesses AAS using HTTP REST calls
-		WebServiceJSONClient jsonClient = new WebServiceJSONClient();
-		
-		// Read property values using the WebServiceJSONClient class. 
-		// - Returned property contains meta data. The actual property is stored in property "entity", property value is in entity property "value"
-		String smEndpoint = "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/dynamicModelRepository/aas/submodels/Status";
-		Map<String, Object> sm = ((Map<String, Object>) jsonClient.get(smEndpoint));
-		String smId = (String) sm.get("idShort");
-		int prop1Val = (int) ((Map<String, Object>) jsonClient.get(smEndpoint + "/" + SubmodelElementProvider.PROPERTIES + "/prop1")).get("value");
-		String prop1Id = (String) ((Map<String, Object>) jsonClient.get(smEndpoint + "/" + SubmodelElementProvider.PROPERTIES + "/prop1")).get("idShort");
-		String prop2Val = (String) ((Map<String, Object>) jsonClient.get(smEndpoint + "/" + SubmodelElementProvider.PROPERTIES + "/prop2")).get("value");
-
-		
-		// Check results
-		assertTrue(smId.equals("Status"));
-		assertTrue(prop1Val == 7);
-		assertTrue(prop1Id.equals("prop1"));
-		assertTrue(prop2Val.equals("myStr"));
-	}
-}
-
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/submodels/InvokeSubModelOperationSDK.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/submodels/InvokeSubModelOperationSDK.java
deleted file mode 100644
index d608f14..0000000
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/submodels/InvokeSubModelOperationSDK.java
+++ /dev/null
@@ -1,144 +0,0 @@
-package org.eclipse.basyx.examples.snippets.aas.submodels;
-
-import static org.junit.Assert.assertTrue;
-
-import java.util.Map;
-import java.util.function.Function;
-
-import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
-import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
-import org.eclipse.basyx.components.servlet.submodel.SubmodelServlet;
-import org.eclipse.basyx.examples.contexts.BaSyxExamplesContext_Empty;
-import org.eclipse.basyx.examples.deployment.BaSyxDeployment;
-import org.eclipse.basyx.examples.support.directory.ExampleAASRegistry;
-import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
-import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperation;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
-import org.junit.ClassRule;
-import org.junit.Test;
-
-/**
- * Code snippet that illustrates the definition and invocation of sub model operations
- * 
- * The snippet communicates with a VAB element that is deployed to a VABLambdaServlet on a
- * Apache Tomcat HTTP server instance. The VABLambdaServlet provides an empty container that
- * is able to host any VAB object.
- * 
- * @author kuhn
- *
- */
-public class InvokeSubModelOperationSDK {
-
-	
-	/**
-	 * Example sub model. This example sub model is created with the BaSyx SDK factory and defines the AAS meta model properties
-	 */
-	static class SampleSubModel extends SubModel {
-		/**
-		 * Constructor - create sub model
-		 * 
-		 * This sub model contains operations
-		 */
-		public SampleSubModel() {
-			// Set sub model ID
-			setIdShort("sm-001");
-
-			// Define operations
-			Operation op1 = new Operation((Function<Object[], Object>) v -> {
-				return operation1();
-			});
-			op1.setIdShort("operation1");
-			addSubModelElement(op1);
-
-			Operation op2 = new Operation((Function<Object[], Object>) v -> {
-				return operation2((int) v[0], (int) v[1]);
-			});
-			op2.setIdShort("operation2");
-			addSubModelElement(op2);
-
-		}
-		
-		/**
-		 * Example operation implementation
-		 */
-		public int operation1() {
-			return 4;
-		}
-		
-		/**
-		 * Example operation with parameter
-		 */
-		public int operation2(int par1, int par2) {
-			return par1+par2;
-		}
-	}
-
-	
-	
-	/**
-	 * Create VAB connection manager backend
-	 * 
-	 * The connection manager uses a preconfigured directory for resolving IDs to 
-	 * network addresses, and a HTTP connector to connect to VAB objects.
-	 */
-	protected ConnectedAssetAdministrationShellManager manager = new ConnectedAssetAdministrationShellManager(
-			// Add example specific mappings
-			new ExampleAASRegistry()
-					.addAASMapping("aas-001", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/SampleModel/")
-					.addSubmodelMapping("aas-001", "sm-001", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/SampleModel/"),
-			// We connect via HTTP
-			new HTTPConnectorProvider());
-	
-	
-	/**
-	 * The BaSyx Deployment instantiates and starts context elements for this example. 
-	 * 
-	 * This example instantiates the BaSyxExamplesContext_1MemoryAASServer_1SQLDirectory
-	 * example context that creates one AAS server, and one SQL based AAS registry.
-	 * 
-	 * BaSyxDeployment contexts instantiate all components on the IP address of the host. 
-	 * Therefore, all components use the same IP address. 
-	 */
-	@ClassRule
-	public static BaSyxDeployment context = new BaSyxDeployment(
-				// Servlets for example snippet
-				new BaSyxExamplesContext_Empty().
-					// Deploy example specific servlets to Tomcat server in this context
-					addServletMapping("/Testsuite/components/BaSys/1.0/SampleModel/*",  new SubmodelServlet(new SampleSubModel()))
-			);
-
-	
-	/**
-	 * Run code snippet. Access sub model, query data
-	 */
-	@Test
-	public void accessSubModel() throws Exception {
-		// Retrieve sub model (created by factory) with SDK connector
-		{
-			// Create and connect SDK connector
-			ISubModel subModel = manager.retrieveSubModel(new ModelUrn("aas-001"), new ModelUrn("sm-001"));
-			
-			// Sub model operations
-			Map<String, IOperation> operations = subModel.getOperations();
-			
-			// Get first operation by name
-			IOperation op1 = operations.get("operation1");
-			// - Invoke operation
-			int result1 = (int) op1.invoke();
-
-			// Get second operation by name
-			IOperation op2 = operations.get("operation2");
-			// - Invoke operation
-			int result2 = (int) op2.invoke(7, 5);
-
-			
-			// Check results
-			assertTrue(result1 ==  4);
-			assertTrue(result2 == 12);
-		}
-	}
-}
-
-
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/manager/TestAddSubmodelToAAS.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/manager/TestAddSubmodelToAAS.java
new file mode 100644
index 0000000..1bdd3ae
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/manager/TestAddSubmodelToAAS.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.manager;
+
+import static org.junit.Assert.assertEquals;
+
+import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
+import org.eclipse.basyx.examples.snippets.AbstractSnippetTest;
+import org.eclipse.basyx.examples.support.ExampleComponentBuilder;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.junit.Test;
+
+/**
+ * Test for the AddSubmodelToAAS snippet
+ * 
+ * @author conradi
+ *
+ */
+public class TestAddSubmodelToAAS extends AbstractSnippetTest {
+
+	private static final String NEW_SM_ID_SHORT = "smIdShort_New";
+	private static final String NEW_SM_ID = "smId_New";
+	
+	@Test
+	public void testAddSubmodelToAAS() {
+		
+		// Get the example AAS and Submodel
+		Submodel submodel = ExampleComponentBuilder.buildExampleSubmodel(NEW_SM_ID_SHORT, NEW_SM_ID);
+
+		// Get the Identifiers for the AAS and the Submodel
+		IIdentifier aasIdentifier = new Identifier(IdentifierType.CUSTOM, AAS_ID);
+		IIdentifier smIdentifier = submodel.getIdentification();
+		
+		// Add the Submodel to the AAS
+		AddSubmodelToAAS.addSubmodelToAAS(submodel, aasIdentifier, registryComponent.getRegistryPath());
+		
+		// Check if the Submodel was correctly added
+		ConnectedAssetAdministrationShellManager manager = getManager();
+		ISubmodel remoteSM = manager.retrieveSubmodel(aasIdentifier, smIdentifier);
+		assertEquals(NEW_SM_ID_SHORT, remoteSM.getIdShort());
+		
+	}
+	
+}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/manager/TestDeleteAAS.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/manager/TestDeleteAAS.java
new file mode 100644
index 0000000..4ec5bbd
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/manager/TestDeleteAAS.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.manager;
+
+import static org.junit.Assert.fail;
+
+import org.eclipse.basyx.examples.snippets.AbstractSnippetTest;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.junit.Test;
+
+/**
+ * Test for the DeleteAAS snippet
+ * 
+ * @author conradi
+ *
+ */
+public class TestDeleteAAS extends AbstractSnippetTest {
+
+	@Test
+	public void testDeleteAAS() {
+		
+		// Get the Identifier of the example AAS
+		IIdentifier aasIdentifier = new Identifier(IdentifierType.CUSTOM, AAS_ID);
+		
+		// Delete the AAS
+		DeleteAAS.deleteAAS(aasIdentifier, registryComponent.getRegistryPath());
+		
+		// Try to retrieve deleted AAS; should throw ResourceNotFoundException
+		try {
+			RetrieveAAS.retrieveRemoteAAS(aasIdentifier, registryComponent.getRegistryPath());
+			fail();
+		} catch (ResourceNotFoundException e) {
+		}
+		
+	}
+	
+}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/manager/TestDeleteSubmodelFromAAS.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/manager/TestDeleteSubmodelFromAAS.java
new file mode 100644
index 0000000..ed8cdbf
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/manager/TestDeleteSubmodelFromAAS.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.manager;
+
+import static org.junit.Assert.fail;
+
+import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
+import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
+import org.eclipse.basyx.examples.snippets.AbstractSnippetTest;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.junit.Test;
+
+/**
+ * Test for the DeleteSubmodelFromAAS snippet
+ * 
+ * @author conradi
+ *
+ */
+public class TestDeleteSubmodelFromAAS extends AbstractSnippetTest {
+
+	@Test
+	public void testDeleteSubmodel() {
+		
+		// Get the Identifier of the example AAS and Submodel
+		IIdentifier aasIdentifier = new Identifier(IdentifierType.CUSTOM, AAS_ID);
+		IIdentifier smIdentifier = new Identifier(IdentifierType.CUSTOM, SM_ID);
+		
+		// Delete the Submodel
+		DeleteSubmodelFromAAS.deleteSubmodelFromAAS(smIdentifier, aasIdentifier, registryComponent.getRegistryPath());		
+		
+		// Get the AAS as ConnectedAAS
+		ConnectedAssetAdministrationShellManager manager = getManager();
+		IAssetAdministrationShell aas = manager.retrieveAAS(aasIdentifier);
+		
+		// Try to retrieve deleted Submodel; should throw ResourceNotFoundException
+		try {
+			aas.getSubmodel(smIdentifier);
+			fail();
+		} catch (ResourceNotFoundException e) {
+		}
+		
+	}
+	
+}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/manager/TestPushAASToServer.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/manager/TestPushAASToServer.java
new file mode 100644
index 0000000..383db6f
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/manager/TestPushAASToServer.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.manager;
+
+import static org.junit.Assert.assertEquals;
+
+import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
+import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+import org.eclipse.basyx.examples.snippets.AbstractSnippetTest;
+import org.eclipse.basyx.examples.support.ExampleComponentBuilder;
+import org.junit.Test;
+
+/**
+ * Test for the PushAASToServer snippet
+ * 
+ * @author conradi
+ *
+ */
+public class TestPushAASToServer extends AbstractSnippetTest {
+	
+	protected static final String NEW_AAS_ID_SHORT = "aasIdShort_New";
+	protected static final String NEW_AAS_ID = "aasId_New";
+	
+	@Test
+	public void testPushAAS() throws Exception {
+		
+		// Get the example AAS
+		AssetAdministrationShell aas = ExampleComponentBuilder.buildExampleAAS(NEW_AAS_ID_SHORT, NEW_AAS_ID);
+		
+		// Push the AAS to the server
+		PushAASToServer.pushAAS(aas, aasComponent.getAASServerPath(), registryComponent.getRegistryPath());
+		
+		// Check if the AAS is present on the server
+		ConnectedAssetAdministrationShellManager manager = getManager();
+		IAssetAdministrationShell remoteAAS = manager.retrieveAAS(aas.getIdentification());
+		assertEquals(NEW_AAS_ID_SHORT, remoteAAS.getIdShort());
+	}
+	
+}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/manager/TestRetrieveAAS.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/manager/TestRetrieveAAS.java
new file mode 100644
index 0000000..5cfd00f
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/manager/TestRetrieveAAS.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.manager;
+
+import static org.junit.Assert.assertEquals;
+
+import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
+import org.eclipse.basyx.examples.snippets.AbstractSnippetTest;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.junit.Test;
+
+/**
+ * Test for the RetrieveRemoteAAS snippet
+ * 
+ * @author conradi
+ *
+ */
+public class TestRetrieveAAS extends AbstractSnippetTest {
+	
+	@Test
+	public void testRetrieveRemoteAAS() {
+		
+		// Get the Identifier of the example AAS
+		IIdentifier aasIdentifier = new Identifier(IdentifierType.CUSTOM, AAS_ID);
+		
+		// Retrieve the AAS from the server
+		IAssetAdministrationShell remoteAAS =
+				RetrieveAAS.retrieveRemoteAAS(aasIdentifier, registryComponent.getRegistryPath());
+		
+		// Check if the retrieved AAS can be used correctly
+		assertEquals(AAS_ID_SHORT, remoteAAS.getIdShort());
+	}
+}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/manager/TestRetrieveSubmodelFromAAS.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/manager/TestRetrieveSubmodelFromAAS.java
new file mode 100644
index 0000000..2a12e39
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/manager/TestRetrieveSubmodelFromAAS.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.manager;
+
+import static org.junit.Assert.assertEquals;
+
+import org.eclipse.basyx.examples.snippets.AbstractSnippetTest;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.junit.Test;
+
+/**
+ * Test for the RetrieveSubmodelFromAAS snippet
+ * 
+ * @author conradi
+ *
+ */
+public class TestRetrieveSubmodelFromAAS extends AbstractSnippetTest {
+
+	
+	@Test
+	public void testRetrieveSubmodelFromAAS() {
+		
+		// Get the Identifiers of the AAS and Submodel
+		IIdentifier aasIdentifier = new Identifier(IdentifierType.CUSTOM, AAS_ID);
+		IIdentifier smIdentifier = new Identifier(IdentifierType.CUSTOM, SM_ID);
+		
+		// Get the Submodel from the server
+		ISubmodel remoteSubmodel = RetrieveSubmodelFromAAS.retrieveSubmodelFromAAS(
+				smIdentifier, aasIdentifier, registryComponent.getRegistryPath());
+		
+		// Check if the Submodel can be used correctly
+		assertEquals(SM_ID_SHORT, remoteSubmodel.getIdShort());
+	}
+	
+}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/property/TestCreateLambdaProperty.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/property/TestCreateLambdaProperty.java
new file mode 100644
index 0000000..a34153c
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/property/TestCreateLambdaProperty.java
@@ -0,0 +1,80 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.property;
+
+import static org.junit.Assert.assertEquals;
+
+import org.eclipse.basyx.aas.metamodel.map.descriptor.CustomId;
+import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
+import org.eclipse.basyx.examples.snippets.submodel.HostPreconfiguredSubmodel;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
+import org.eclipse.basyx.submodel.metamodel.connected.ConnectedSubmodel;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.vab.coder.json.connector.JSONConnector;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnector;
+import org.eclipse.basyx.vab.protocol.http.server.BaSyxHTTPServer;
+import org.junit.After;
+import org.junit.Test;
+
+/**
+ * Test for the CreateLambdaProperty snippet
+ * 
+ * @author schnicke
+ *
+ */
+public class TestCreateLambdaProperty {
+
+	// Value to be facaded by the lambda property
+	private int testValue = 15;
+
+	// Used for test case tear down
+	private BaSyxHTTPServer server;
+
+	@Test
+	public void testCreateLambdaProperty() {
+		// The type cast in the setter is necessary due to the Consumer<Object> definition
+		Property lambdaProp = CreateLambdaProperty.createLambdaProperty("lambdaProp", ValueType.Integer, () -> testValue, (v) -> testValue = (int) v);
+
+		// Package it in a test submodel and host it
+		Submodel sm = new Submodel("testSubmodelIdShort", new CustomId("testSubmodelId"));
+		sm.addSubmodelElement(lambdaProp);
+		
+		// Create the context configuration and host the submodel containg the lambda property
+		BaSyxContextConfiguration config = new BaSyxContextConfiguration(4040, "");
+		server = HostPreconfiguredSubmodel.hostPreconfiguredSubmodel(config, sm);
+
+		// Here, for simplicity reason of the test, the ConnectedSubmodel is created by hand.
+		// In a real-world application, the AASManager would be used instead.
+		String smPath = "http://localhost:4040/" + sm.getIdShort() + "/submodel";
+
+		ConnectedSubmodel cSm = new ConnectedSubmodel(new VABElementProxy("", new JSONConnector(new HTTPConnector(smPath))));
+		IProperty cLambdaProp = (IProperty) cSm.getSubmodelElement(lambdaProp.getIdShort());
+
+		// Test getting
+		assertEquals(testValue, cLambdaProp.getValue());
+
+		// Test setting
+		int newVal = 100;
+		cLambdaProp.setValue(newVal);
+		assertEquals(newVal, cLambdaProp.getValue());
+		assertEquals(newVal, testValue);
+	}
+
+	// Ensures that the started server is shut down regardless of test result
+	@After
+	public void tearDown() {
+		if (server != null) {
+			server.shutdown();
+		}
+	}
+}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/registry/TestDeregisterAAS.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/registry/TestDeregisterAAS.java
new file mode 100644
index 0000000..b8ea95b
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/registry/TestDeregisterAAS.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.registry;
+
+import static org.junit.Assert.fail;
+
+import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
+import org.eclipse.basyx.examples.snippets.AbstractSnippetTest;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.junit.Test;
+
+/**
+ * Test for the DeregisterAAS Snippet
+ * 
+ * @author conradi
+ *
+ */
+public class TestDeregisterAAS extends AbstractSnippetTest {
+
+	@Test
+	public void testDeregisterAAS() {
+		
+		// Get the Identifier of the example AAS
+		IIdentifier aasIdentifier = new Identifier(IdentifierType.CUSTOM, AAS_ID);
+		
+		DeregisterAAS.registerAAS(aasIdentifier, registryComponent.getRegistryPath());
+		
+		// Lookup the AAS in the registry
+		AASRegistryProxy registry = new AASRegistryProxy(registryComponent.getRegistryPath());
+		
+		try {
+			registry.lookupAAS(aasIdentifier);
+			fail();
+		} catch (ResourceNotFoundException e) {
+		}	
+	}
+	
+}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/registry/TestDeregisterSubmodel.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/registry/TestDeregisterSubmodel.java
new file mode 100644
index 0000000..ba106d4
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/registry/TestDeregisterSubmodel.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.registry;
+
+import static org.junit.Assert.fail;
+
+import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
+import org.eclipse.basyx.examples.snippets.AbstractSnippetTest;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.junit.Test;
+
+/**
+ * Test for the DeregisterSubmodel Snippet
+ * 
+ * @author conradi
+ *
+ */
+public class TestDeregisterSubmodel extends AbstractSnippetTest {
+
+	@Test
+	public void testDeregisterSubmodel() {
+		
+		// Get the Identifier of the example AAS
+		IIdentifier aasIdentifier = new Identifier(IdentifierType.CUSTOM, AAS_ID);
+		IIdentifier smIdentifier = new Identifier(IdentifierType.CUSTOM, SM_ID);
+		
+		DeregisterSubmodel.registerSubmodel(smIdentifier, aasIdentifier, registryComponent.getRegistryPath());
+		
+		// Lookup the AAS in the registry
+		AASRegistryProxy registry = new AASRegistryProxy(registryComponent.getRegistryPath());
+		
+		try {
+			registry.lookupSubmodel(aasIdentifier, smIdentifier);
+			fail();
+		} catch (ResourceNotFoundException e) {
+		}	
+	}
+	
+}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/registry/TestLookupAAS.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/registry/TestLookupAAS.java
new file mode 100644
index 0000000..8f06ac0
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/registry/TestLookupAAS.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.registry;
+
+import static org.junit.Assert.assertEquals;
+
+import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
+import org.eclipse.basyx.examples.snippets.AbstractSnippetTest;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.junit.Test;
+
+/**
+ * Test for the LookupAAS snippet
+ * 
+ * @author conradi
+ *
+ */
+public class TestLookupAAS extends AbstractSnippetTest {
+
+	@Test
+	public void testLookupAAS() {
+		
+		// Get the Identifier of the example AAS
+		IIdentifier aasIdentifier = new Identifier(IdentifierType.CUSTOM, AAS_ID);
+		
+		// Lookup the AAS in the registry
+		AASDescriptor descriptor = LookupAAS.lookupAAS(aasIdentifier, registryComponent.getRegistryPath());
+		
+		// Check if the returned Descriptor is as expected
+		assertEquals(AAS_ENDPOINT, descriptor.getFirstEndpoint());
+		
+	}
+	
+}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/registry/TestLookupSubmodel.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/registry/TestLookupSubmodel.java
new file mode 100644
index 0000000..f456fbc
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/registry/TestLookupSubmodel.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.registry;
+
+import static org.junit.Assert.assertEquals;
+
+import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
+import org.eclipse.basyx.examples.snippets.AbstractSnippetTest;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.junit.Test;
+
+/**
+ * Test for the LookupSubmodel snippet
+ * 
+ * @author conradi
+ *
+ */
+public class TestLookupSubmodel extends AbstractSnippetTest {
+
+	@Test
+	public void testLookupSubmodel() {
+		
+		// Get the Identifiers of the AAS and Submodel
+		IIdentifier aasIdentifier = new Identifier(IdentifierType.CUSTOM, AAS_ID);
+		IIdentifier smIdentifier = new Identifier(IdentifierType.CUSTOM, SM_ID);
+		
+		// Lookup the Submodel in the registry
+		SubmodelDescriptor descriptor = LookupSubmodel.lookupSubmodel(
+				smIdentifier, aasIdentifier, registryComponent.getRegistryPath());
+		
+		// Check if the returned Descriptor is as expected
+		assertEquals(SM_ENDPOINT, descriptor.getFirstEndpoint());
+		
+	}
+	
+}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/registry/TestRegisterAAS.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/registry/TestRegisterAAS.java
new file mode 100644
index 0000000..fe42cdb
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/registry/TestRegisterAAS.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.registry;
+
+import static org.junit.Assert.assertEquals;
+
+import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
+import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
+import org.eclipse.basyx.examples.snippets.AbstractSnippetTest;
+import org.eclipse.basyx.examples.support.ExampleComponentBuilder;
+import org.junit.Test;
+
+/**
+ * Test for the RegisterAAS snippet
+ * 
+ * @author conradi
+ *
+ */
+public class TestRegisterAAS extends AbstractSnippetTest {
+	
+	protected static final String NEW_AAS_ID_SHORT = "aasIdShort_New";
+	protected static final String NEW_AAS_ID = "aasId_New";
+	protected static final String NEW_AAS_ENDPOINT = "http://localhost:8080/aasComponent/shells/" + NEW_AAS_ID + "/aas";
+	
+	@Test
+	public void testRegisterAAS() {
+		
+		// Get the example AAS
+		AssetAdministrationShell aas = ExampleComponentBuilder.buildExampleAAS(NEW_AAS_ID_SHORT, NEW_AAS_ID);
+		
+		// Register this AAS
+		RegisterAAS.registerAAS(aas, NEW_AAS_ENDPOINT, registryComponent.getRegistryPath());
+		
+		// Check if the AAS was correctly registered
+		AASRegistryProxy registryProxy = new AASRegistryProxy(registryComponent.getRegistryPath());
+		AASDescriptor descriptor = registryProxy.lookupAAS(aas.getIdentification());
+		assertEquals(NEW_AAS_ENDPOINT, descriptor.getFirstEndpoint());
+		
+	}
+	
+}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/registry/TestRegisterSubmodel.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/registry/TestRegisterSubmodel.java
new file mode 100644
index 0000000..e9b02ba
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/registry/TestRegisterSubmodel.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.registry;
+
+import static org.junit.Assert.assertEquals;
+
+import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
+import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
+import org.eclipse.basyx.examples.snippets.AbstractSnippetTest;
+import org.eclipse.basyx.examples.support.ExampleComponentBuilder;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.junit.Test;
+
+/**
+ * Test for the RegisterSubmodel snippet
+ * 
+ * @author conradi
+ *
+ */
+public class TestRegisterSubmodel extends AbstractSnippetTest {
+
+	private static final String NEW_SM_ID_SHORT = "smIdShort_New";
+	private static final String NEW_SM_ID = "smId_New";
+	private static final String NEW_SM_ENDPOINT = "http://localhost:8080/aasComponent/" + NEW_SM_ID_SHORT + "/submodel";
+	
+	@Test
+	public void testRegisterSubmodel() {
+		
+		// Get the example AAS and Submodel
+		AssetAdministrationShell aas = ExampleComponentBuilder.buildExampleAAS(AAS_ID_SHORT, AAS_ID);
+		Submodel sm = ExampleComponentBuilder.buildExampleSubmodel(NEW_SM_ID_SHORT, NEW_SM_ID);
+		
+		// Register this AAS
+		RegisterAAS.registerAAS(aas, AAS_ENDPOINT, registryComponent.getRegistryPath());
+		
+		// Register this Submodel
+		RegisterSubmodel.registerSubmodel(sm, NEW_SM_ENDPOINT, aas.getIdentification(), registryComponent.getRegistryPath());
+		
+		// Check if the Submodel was correctly registered
+		AASRegistryProxy registryProxy = new AASRegistryProxy(registryComponent.getRegistryPath());
+		SubmodelDescriptor descriptor = registryProxy.lookupSubmodel(aas.getIdentification(), sm.getIdentification());
+		assertEquals(NEW_SM_ENDPOINT, descriptor.getFirstEndpoint());
+		
+	}
+}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/submodel/TestAddSubmodelElement.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/submodel/TestAddSubmodelElement.java
new file mode 100644
index 0000000..ae32c33
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/submodel/TestAddSubmodelElement.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.submodel;
+
+import static org.junit.Assert.assertEquals;
+
+import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
+import org.eclipse.basyx.examples.snippets.AbstractSnippetTest;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.junit.Test;
+
+/**
+ * Test for the AddSubmodelElement snippet
+ * 
+ * @author conradi
+ *
+ */
+public class TestAddSubmodelElement extends AbstractSnippetTest {
+
+	private static final String NEW_PROPERTY_ID = "new_prop";
+	private static final int NEW_PROPERTY_VALUE = 321;
+	
+	@Test
+	public void testAddSubmodelElement() {
+		
+		// Get the Identifiers of the AAS and Submodel
+		IIdentifier aasIdentifier = new Identifier(IdentifierType.CUSTOM, AAS_ID);
+		IIdentifier smIdentifier = new Identifier(IdentifierType.CUSTOM, SM_ID);
+		
+		// Build a new SubmodelElement
+		Property newProperty = new Property();
+		newProperty.setIdShort(NEW_PROPERTY_ID);
+		newProperty.setValue(NEW_PROPERTY_VALUE);
+		
+		// Add the new Element to the Submodel
+		AddSubmodelElement.addSubmodelElement(newProperty, smIdentifier, aasIdentifier, registryComponent.getRegistryPath());
+		
+		// Get the Element from the server
+		ConnectedAssetAdministrationShellManager manager = getManager();
+		ISubmodel remoteSubmodel = manager.retrieveSubmodel(aasIdentifier, smIdentifier);
+		ISubmodelElement remoteElement = remoteSubmodel.getSubmodelElement(NEW_PROPERTY_ID);
+		
+		// Check if its value is as expected
+		assertEquals(NEW_PROPERTY_VALUE, remoteElement.getValue());
+	}
+	
+}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/submodel/TestCreateSubmodel.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/submodel/TestCreateSubmodel.java
new file mode 100644
index 0000000..f6a71c2
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/submodel/TestCreateSubmodel.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.submodel;
+
+import static org.junit.Assert.assertEquals;
+
+import org.eclipse.basyx.examples.snippets.AbstractSnippetTest;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.junit.Test;
+
+/**
+ * Test for the CreateSubmodel snippet
+ * 
+ * @author conradi
+ *
+ */
+public class TestCreateSubmodel extends AbstractSnippetTest {
+
+	private static final String SM_ID_SHORT = "smIdShort";
+	private static final String SM_ID = "smId";
+	
+	private static final String PROPERTY_ID_SHORT = "propIdShort";
+	private static final String PROPERTY_VALUE = "value";
+	
+	
+	@Test
+	public void testCreateSubmodel() {
+		
+		// Create a Submodel
+		Submodel sm = CreateSubmodel.createSubmodel(SM_ID_SHORT, new Identifier(IdentifierType.CUSTOM, SM_ID), PROPERTY_ID_SHORT, PROPERTY_VALUE);
+		
+		// Check the created Submodel
+		assertEquals(SM_ID_SHORT, sm.getIdShort());
+		assertEquals(SM_ID, sm.getIdentification().getId());
+		
+		// Get the Property from the Submodel
+		// This will throw an Exception if an Element with the given Id does not exist
+		ISubmodelElement property = sm.getSubmodelElement(PROPERTY_ID_SHORT);
+		
+		// Check the Property
+		assertEquals(property.getIdShort(), PROPERTY_ID_SHORT);
+		assertEquals(property.getValue(), PROPERTY_VALUE);
+	}
+	
+}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/submodel/TestDeleteSubmodelElement.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/submodel/TestDeleteSubmodelElement.java
new file mode 100644
index 0000000..e54c605
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/submodel/TestDeleteSubmodelElement.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.submodel;
+
+import static org.junit.Assert.fail;
+
+import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
+import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
+import org.eclipse.basyx.examples.snippets.AbstractSnippetTest;
+import org.eclipse.basyx.examples.support.ExampleComponentBuilder;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.junit.Test;
+
+/**
+ * Test for the DeleteSubmodelElement snippet
+ * 
+ * @author conradi
+ *
+ */
+public class TestDeleteSubmodelElement extends AbstractSnippetTest {
+
+	@Test
+	public void testDeleteSubmodelElement() {
+		
+		// Get the Identifier of the example AAS and Submodel
+		IIdentifier aasIdentifier = new Identifier(IdentifierType.CUSTOM, AAS_ID);
+		IIdentifier smIdentifier = new Identifier(IdentifierType.CUSTOM, SM_ID);
+		
+		// Delete the SubmodelElement
+		DeleteSubmodelElement.deleteSubmodelElement(ExampleComponentBuilder.PROPERTY_ID, smIdentifier, aasIdentifier, registryComponent.getRegistryPath());
+		
+		// Create a proxy pointing to the registry server
+		AASRegistryProxy registryProxy = new AASRegistryProxy(registryComponent.getRegistryPath());
+		
+		// Create a ConnectedAASManager using the registryProxy as its registry
+		ConnectedAssetAdministrationShellManager manager =
+				new ConnectedAssetAdministrationShellManager(registryProxy);
+		
+		// Retrieve the Submodel from the server as a ConnectedSubmodel
+		ISubmodel submodel = manager.retrieveSubmodel(aasIdentifier, smIdentifier);
+		
+		// Try to retrieve deleted SubmodelElement; should throw ResourceNotFoundException
+		try {
+			submodel.getSubmodelElement(ExampleComponentBuilder.PROPERTY_ID);
+			fail();
+		} catch (ResourceNotFoundException e) {
+		}
+		
+	}
+	
+}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/submodel/TestExecuteOperation.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/submodel/TestExecuteOperation.java
new file mode 100644
index 0000000..e532841
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/submodel/TestExecuteOperation.java
@@ -0,0 +1,122 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.submodel;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.function.Function;
+
+import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
+import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
+import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
+import org.eclipse.basyx.components.servlet.submodel.SubmodelServlet;
+import org.eclipse.basyx.examples.snippets.AbstractSnippetTest;
+import org.eclipse.basyx.examples.support.ExampleComponentBuilder;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.OperationVariable;
+import org.eclipse.basyx.vab.protocol.http.server.BaSyxHTTPServer;
+import org.eclipse.basyx.vab.protocol.http.server.BaSyxContext;
+import org.junit.After;
+import org.junit.Test;
+
+/**
+ * Test for the ExecuteOperation snippet
+ * 
+ * @author conradi
+ *
+ */
+public class TestExecuteOperation extends AbstractSnippetTest {
+
+	private static final String NEW_SM_ID_SHORT = "smIdShort_New";
+	private static final String NEW_SM_ID = "smId_New";
+	
+	private static final String OPERATION_ID = "operation";
+	
+	private static final Object[] PARAMETERS = {2, 3};
+	private static final int EXPECTED_RESULT = 5;
+	
+	private BaSyxHTTPServer server;
+	
+	@After
+	public void shutdownServer() {
+		server.shutdown();
+	}
+	
+	@Test
+	public void testExecuteOperation() throws Exception {
+		
+		Submodel submodel = ExampleComponentBuilder.buildExampleSubmodel(NEW_SM_ID_SHORT, NEW_SM_ID);
+		
+		// Add an Operation which calculates the sum of the two parameters
+		Operation operation = new Operation((Function<Object[], Object>) v -> {
+			return (int) v[0] + (int) v[1];
+		});
+		OperationVariable a = new OperationVariable(new Property("a", 1));
+		OperationVariable b = new OperationVariable(new Property("b", 2));
+		OperationVariable r = new OperationVariable(new Property("r", 3));
+		operation.setInputVariables(Arrays.asList(a, b));
+		operation.setOutputVariables(Collections.singletonList(r));
+		operation.setIdShort(OPERATION_ID);
+		submodel.addSubmodelElement(operation);
+		
+		// Startup a Server hosting this Submodel
+		provideSubmodel(submodel);
+		
+		
+		// Get the Identifiers of the AAS and Submodel
+		IIdentifier aasIdentifier = new Identifier(IdentifierType.CUSTOM, AAS_ID);
+		IIdentifier smIdentifier = new Identifier(IdentifierType.CUSTOM, NEW_SM_ID);
+		
+		// Execute the Operation and get the result
+		Object result = ExecuteOperation.executeOperation(OPERATION_ID, PARAMETERS, smIdentifier, aasIdentifier, registryComponent.getRegistryPath());
+		
+		// Check if the result is the expected value
+		assertEquals(EXPECTED_RESULT, result);
+		
+	}
+	
+	/**
+	 * Starts a new server hosting a given Submodel
+	 * This is necessary as an Operation can not be transfered to a server via serialization
+	 * 
+	 * @param submodel the Submodel to be hosted
+	 */
+	private void provideSubmodel(Submodel submodel) {
+		// Create a BaSyxConetxt for port 8082 with an empty endpoint
+		BaSyxContextConfiguration contextConfig = new BaSyxContextConfiguration(8082, "");
+		BaSyxContext context = contextConfig.createBaSyxContext();
+		
+		// Create a new SubmodelServlet containing the submodel
+		SubmodelServlet smServlet = new SubmodelServlet(submodel);
+		
+		// Add the SubmodelServlet mapping to the context at the path "/submodel"
+		context.addServletMapping("/submodel/*", smServlet);
+		
+		
+		// Create and start a HTTP server with the context created above
+		server = new BaSyxHTTPServer(context);
+		server.start();
+		
+		IIdentifier aasIdentifier = new Identifier(IdentifierType.CUSTOM, AAS_ID);
+		SubmodelDescriptor descriptor = new SubmodelDescriptor(submodel, "http://localhost:8082/submodel");
+		
+		// Register the new Submodel
+		AASRegistryProxy registry = new AASRegistryProxy(registryComponent.getRegistryPath());
+		registry.register(aasIdentifier, descriptor);
+	}
+	
+}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/submodel/TestHostPreconfiguredSubmodel.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/submodel/TestHostPreconfiguredSubmodel.java
new file mode 100644
index 0000000..7be629b
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/submodel/TestHostPreconfiguredSubmodel.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.submodel;
+
+
+import static org.junit.Assert.assertEquals;
+
+import org.eclipse.basyx.aas.metamodel.map.descriptor.CustomId;
+import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
+import org.eclipse.basyx.submodel.metamodel.connected.ConnectedSubmodel;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.vab.coder.json.connector.JSONConnector;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnector;
+import org.eclipse.basyx.vab.protocol.http.server.BaSyxHTTPServer;
+import org.junit.After;
+import org.junit.Test;
+
+/**
+ * Test for the HostPreconfiguredSubmodel snippet
+ * 
+ * @author schnicke
+ *
+ */
+public class TestHostPreconfiguredSubmodel {
+
+	// Used for test case tear down
+	private BaSyxHTTPServer server;
+
+	@Test
+	public void testHostPreconfiguredSubmodel() {
+		Submodel sm = new Submodel("testSubmodelIdShort", new CustomId("testSubmodel"));
+		BaSyxContextConfiguration contextConfig = new BaSyxContextConfiguration(4040, "");
+		server = HostPreconfiguredSubmodel.hostPreconfiguredSubmodel(contextConfig, sm);
+		String smPath = "http://localhost:4040/" + sm.getIdShort() + "/submodel";
+
+		// Here, for simplicity reason of the test, the ConnectedSubmodel is created by hand. 
+		// In a real-world application, the AASManager would be used instead.
+		ConnectedSubmodel cSm = new ConnectedSubmodel(new VABElementProxy("", new JSONConnector(new HTTPConnector(smPath))));
+		assertEquals(sm.getIdentification(), cSm.getIdentification());
+	}
+
+	// Ensures that the started server is shut down regardless of test result
+	@After
+	public void tearDown() {
+		if (server != null) {
+			server.shutdown();
+		}
+	}
+}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/submodel/TestRetrieveSubmodelElement.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/submodel/TestRetrieveSubmodelElement.java
new file mode 100644
index 0000000..c8b6deb
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/submodel/TestRetrieveSubmodelElement.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.examples.snippets.submodel;
+
+import static org.junit.Assert.assertEquals;
+
+import org.eclipse.basyx.examples.snippets.AbstractSnippetTest;
+import org.eclipse.basyx.examples.support.ExampleComponentBuilder;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.junit.Test;
+
+/**
+ * Test for the RetrieveSubmodelElement snippet
+ * 
+ * @author conradi
+ *
+ */
+public class TestRetrieveSubmodelElement extends AbstractSnippetTest {
+
+	
+	@Test
+	public void testRetrieveSubmodelElement() {
+		
+		// Get the Identifiers of the AAS and Submodel
+		IIdentifier aasIdentifier = new Identifier(IdentifierType.CUSTOM, AAS_ID);
+		IIdentifier smIdentifier = new Identifier(IdentifierType.CUSTOM, SM_ID);
+		
+		// Get the idShort and value of the element to be retrieved
+		String elementId = ExampleComponentBuilder.PROPERTY_ID;
+		int elementValue = ExampleComponentBuilder.PROPERTY_VALUE;
+		
+		// Get the SubmodelElement
+		ISubmodelElement element = RetrieveSubmodelElement.retrieveSubmodelElement(
+				elementId, smIdentifier, aasIdentifier, registryComponent.getRegistryPath());
+		
+		// Check if the SubmodelElement contains the expected value
+		assertEquals(elementValue, element.getValue());
+	}
+	
+}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/code/BaSyxCreateProvideUseExampleAASSubmodel.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/code/BaSyxCreateProvideUseExampleAASSubmodel.java
deleted file mode 100644
index dc700af..0000000
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/code/BaSyxCreateProvideUseExampleAASSubmodel.java
+++ /dev/null
@@ -1,66 +0,0 @@
-package org.eclipse.basyx.examples.snippets.undoc.aas.code;
-
-import static org.junit.Assert.assertEquals;
-
-import java.util.Map;
-
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.submodel.restapi.SubModelProvider;
-import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
-import org.eclipse.basyx.vab.coder.json.connector.JSONConnector;
-import org.eclipse.basyx.vab.protocol.basyx.connector.BaSyxConnector;
-import org.eclipse.basyx.vab.protocol.basyx.server.BaSyxTCPServer;
-import org.junit.Test;
-
-/**
- * Illustrate manual creation and providing of AAS sub model
- * 
- * @author kuhn
- *
- */
-public class BaSyxCreateProvideUseExampleAASSubmodel {
-
-	
-	/**
-	 * Create, export, and access an example AAS sub model
-	 */
-	@SuppressWarnings("unchecked")
-	@Test
-	public void createExportAndAccessSubModel() throws Exception {
-				
-		// Create sub model and add properties
-		SubModel statusSM = new SubModel();
-		//   - Property status: indicate device status
-		Property statusProp = new Property("offline");
-		statusProp.setIdShort("status");
-		statusSM.addSubModelElement(statusProp);
-		//   - Property statistics: export invocation statistics for every service
-		//     - invocations: indicate total service invocations. Properties are not persisted in this example,
-		//                    therefore we start counting always at 0.
-		Property invocationsProp = new Property(0);
-		invocationsProp.setIdShort("invocations");
-		statusSM.addSubModelElement(invocationsProp);
-
-		
-		// Provide sub model via BaSyx server
-		BaSyxTCPServer<SubModelProvider> server = new BaSyxTCPServer<>(new SubModelProvider(statusSM), 9998);
-		// - Start local BaSyx/TCP server
-		server.start();
-
-		
-		// Access BaSyx TCP server
-		// - Create BaSyx connector to connect with the sub model
-		BaSyxConnector basyxConnector = new BaSyxConnector("localhost", 9998);
-		// - Create connection to device manager
-		JSONConnector toDeviceManager = new JSONConnector(basyxConnector);	
-		// - Access sub model property, check value
-		Map<String, Object> property = (Map<String, Object>) toDeviceManager
-				.getModelPropertyValue(SubmodelElementProvider.PROPERTIES + "/status");
-		assertEquals("offline", property.get("value"));
-		
-		
-		// Stop local BaSyx/TCP server
-		server.stop();
-	}
-}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/connection/servlet/AASServletConnection.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/connection/servlet/AASServletConnection.java
deleted file mode 100644
index 59b886f..0000000
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/connection/servlet/AASServletConnection.java
+++ /dev/null
@@ -1,142 +0,0 @@
-package org.eclipse.basyx.examples.snippets.undoc.aas.connection.servlet;
-
-import static org.junit.Assert.assertTrue;
-
-import java.util.Map;
-
-import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
-import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
-import org.eclipse.basyx.components.servlet.submodel.SubmodelServlet;
-import org.eclipse.basyx.examples.contexts.BaSyxExamplesContext_Empty;
-import org.eclipse.basyx.examples.deployment.BaSyxDeployment;
-import org.eclipse.basyx.examples.support.directory.ExampleAASRegistry;
-import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
-import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
-import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElementCollection;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
-import org.eclipse.basyx.vab.manager.VABConnectionManager;
-import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
-import org.junit.ClassRule;
-import org.junit.Test;
-
-/**
- * Export sub model through a servlet and connect to that servlet
- * 
- * @author kuhn
- *
- */
-public class AASServletConnection {
-
-	
-	/**
-	 * Example sub model. This example sub model is created with the BaSyx SDK factory and defines the AAS meta model properties
-	 */
-	static class SampleSubModelFactory extends SubModel {
-		/**
-		 * Constructor - create sub model property
-		 */
-		@SuppressWarnings("unchecked")
-		public SampleSubModelFactory() {
-			// Set sub model ID
-			setIdShort("sm-001");
-
-			// Add example properties
-			// - Add simple property
-			Property prop1 = new Property(234);
-			prop1.setIdShort("prop1");
-			addSubModelElement(prop1);
-
-			Property prop11 = new Property(123);
-			prop11.setIdShort("prop11");
-			// - Add container property that holds other properties
-			SubmodelElementCollection container = new SubmodelElementCollection();
-			container.setIdShort("prop2");
-			container.addElement(prop11);
-			// - Add container to property map
-			addSubModelElement(container);
-
-			// Add another property manually to sub model container "properties"
-			Property prop3 = new Property(17);
-			prop3.setIdShort("prop3");
-			{
-				((Map<String, Object>) this.get("submodelElements")).put("prop3", prop3);
-			}
-		}
-	}
-
-	/**
-	 * Create manager using the directory stub an the HTTPConnectorProvider
-	 */
-	ConnectedAssetAdministrationShellManager manager = new ConnectedAssetAdministrationShellManager(
-			// Add example specific mappings
-			new ExampleAASRegistry()
-					.addAASMapping("aas-001", "") // No AAS is provided in this example
-					.addSubmodelMapping("aas-001", "sm-001", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/SampleModel/"),
-			// We connect via HTTP
-			new HTTPConnectorProvider());
-	
-	
-	
-	/**
-	 * VAB connection manager backend
-	 */
-	protected VABConnectionManager connManager = new VABConnectionManager(
-			// Add example specific mappings
-			new ExamplesPreconfiguredDirectory()
-			    // - VAB needs to know the relative path of the sub model that is defined by AAS meta model
-					.addMapping("sm-001VAB", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/SampleModel/"),
-			// We connect via HTTP
-			new HTTPConnectorProvider());
-
-	
-	
-	/**
-	 * Instantiate and start context elements for this example. BaSyxDeployment contexts instantiate all
-	 * components on the IP address of the host. Therefore, all components use the same IP address. 
-	 */
-	@ClassRule
-	public static BaSyxDeployment context = new BaSyxDeployment(
-				// Servlets for example snippet
-				new BaSyxExamplesContext_Empty().
-					// Deploy example specific servlets to Tomcat server in this context
-					addServletMapping("/Testsuite/components/BaSys/1.0/SampleModel/*", new SubmodelServlet(new SampleSubModelFactory())));
-
-	
-	/**
-	 * Connect to sub model, query, and set property values
-	 */
-	@Test @SuppressWarnings("unchecked")
-	public void accessSubModel() throws Exception {
-		// Create and connect SDK connector
-		ISubModel subModel = manager.retrieveSubModel(new ModelUrn("aas-001"), new ModelUrn("sm-001"));
-		// - Retrieve sub model values and compare to expected values
-		assertTrue(subModel.getIdShort().equals("sm-001"));
-		assertTrue(subModel.getProperties().get("prop1").getIdShort().equals("prop1"));
-		assertTrue((int) subModel.getProperties().get("prop1").get() == 234);
-		assertTrue((int) subModel.getProperties().get("prop3").get() == 17);
-		assertTrue(subModel.getSubmodelElements().get("prop2").getIdShort().equals("prop2"));
-		assertTrue((int) ((ISubmodelElementCollection) subModel.getSubmodelElements().get("prop2")).getProperties().get("prop11").get() == 123);
-
-		// Connect to sub model using lower-level VAB interface
-		VABElementProxy connSubModel1 = this.connManager.connectToVABElement("sm-001VAB");
-		// - Read property values and compare with expected values
-		assertTrue((int) ((Map<String, Object>) connSubModel1.getModelPropertyValue(SubmodelElementProvider.PROPERTIES + "/prop1")).get("value") == 234);
-		assertTrue((int) ((Map<String, Object>) connSubModel1.getModelPropertyValue(SubmodelElementProvider.PROPERTIES + "/prop3")).get("value") == 17);
-		assertTrue(((Map<String, Object>) connSubModel1.getModelPropertyValue(SubmodelElementProvider.PROPERTIES + "/prop1")).get("idShort").equals("prop1"));
-		assertTrue(((Map<String, Object>) connSubModel1.getModelPropertyValue(SubmodelElementProvider.PROPERTIES + "/prop2")).get("idShort").equals("prop2"));
-		assertTrue((int) ((Map<String, Object>) connSubModel1.getModelPropertyValue("submodelElements/prop2/prop11")).get("value") == 123);
-		// - Change property value using VAB primitive
-		connSubModel1.setModelPropertyValue(SubmodelElementProvider.PROPERTIES + "/prop1/value", 456);
-		// - Read value back using VAB primitive
-		assertTrue((int) ((Map<String, Object>) connSubModel1.getModelPropertyValue(SubmodelElementProvider.PROPERTIES + "/prop1")).get("value") == 456);
-
-		// Read changed value back using SDK connector
-		assertTrue((int) subModel.getProperties().get("prop1").get() == 456);
-	}
-}
-
-
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/connection/servlet/AASServletConnectionFull.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/connection/servlet/AASServletConnectionFull.java
deleted file mode 100644
index 9e919e8..0000000
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/connection/servlet/AASServletConnectionFull.java
+++ /dev/null
@@ -1,150 +0,0 @@
-package org.eclipse.basyx.examples.snippets.undoc.aas.connection.servlet;
-
-import static org.junit.Assert.assertTrue;
-
-import java.util.Map;
-
-import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
-import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
-import org.eclipse.basyx.components.servlet.submodel.SubmodelServlet;
-import org.eclipse.basyx.examples.contexts.BaSyxExamplesContext_Empty;
-import org.eclipse.basyx.examples.deployment.BaSyxDeployment;
-import org.eclipse.basyx.examples.support.directory.ExampleAASRegistry;
-import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
-import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
-import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElementCollection;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
-import org.eclipse.basyx.vab.manager.VABConnectionManager;
-import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
-import org.junit.ClassRule;
-import org.junit.Test;
-
-
-
-/**
- * Export sub model through a servlet and connect to that servlet
- * 
- * @author kuhn
- *
- */
-public class AASServletConnectionFull {
-
-	
-	/**
-	 * Example sub model. This example sub model is created with the BaSyx SDK factory and defines the AAS meta model properties
-	 */
-	static class SampleSubModelFactory extends SubModel {
-
-		/**
-		 * Constructor - create sub model property
-		 */
-		@SuppressWarnings("unchecked")
-		public SampleSubModelFactory() {
-			// Set sub model ID
-			setIdShort("sm-001");
-
-			// Add example properties
-			// - Add simple property
-			Property prop1 = new Property(234);
-			prop1.setIdShort("prop1");
-			addSubModelElement(prop1);
-
-			Property prop11 = new Property(123);
-			prop11.setIdShort("prop11");
-			// - Add container property that holds other properties
-			SubmodelElementCollection container = new SubmodelElementCollection();
-			container.setIdShort("prop2");
-			container.addElement(prop11);
-			// - Add container to property map
-			addSubModelElement(container);
-
-			// Add another property manually to sub model container "properties"
-			Property prop3 = new Property(17);
-			prop3.setIdShort("prop3");
-			{
-				((Map<String, Object>) this.get("submodelElements")).put("prop3", prop3);
-			}
-		}
-	}
-
-	/**
-	 * VAB connection manager backend
-	 */
-	protected VABConnectionManager connManager = new VABConnectionManager(
-			// Add example specific mappings
-			new ExamplesPreconfiguredDirectory()
-					// - VAB needs to know the relative path of the sub model that is defined by AAS
-					// meta model
-					.addMapping("sm-001VAB", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/SampleModel/")
-					// - VAB needs to know the relative path of the sub model that is defined by AAS
-					// meta model
-					.addMapping("sm-001MVAB", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/SampleModelManual/"),
-			// We connect via HTTP
-			new HTTPConnectorProvider());
-	
-	
-	
-	/**
-	 * VAB connection manager backend
-	 */
-	protected ConnectedAssetAdministrationShellManager manager = new ConnectedAssetAdministrationShellManager(
-			// Add example specific mappings
-			new ExampleAASRegistry()
-					.addAASMapping("aas-001", "") // no AAS is provided in this example
-					.addSubmodelMapping("aas-001", "sm-001", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/SampleModel/"),
-			// We connect via HTTP
-			new HTTPConnectorProvider());
-
-	
-	
-	/**
-	 * Instantiate and start context elements for this example. BaSyxDeployment contexts instantiate all
-	 * components on the IP address of the host. Therefore, all components use the same IP address. 
-	 */
-	@ClassRule
-	public static BaSyxDeployment context = new BaSyxDeployment(
-				// Servlets for example snippet
-				new BaSyxExamplesContext_Empty().
-					// Deploy example specific servlets to Tomcat server in this context
-					addServletMapping("/Testsuite/components/BaSys/1.0/SampleModel/*", new SubmodelServlet(new SampleSubModelFactory())));
-
-	
-	/**
-	 * Connect to sub model, query, and set property values
-	 */
-	@Test @SuppressWarnings("unchecked")
-	public void accessSubModel() throws Exception {
-		// Create and connect SDK connector
-		ISubModel subModel = manager.retrieveSubModel(new ModelUrn("aas-001"), new ModelUrn("sm-001"));
-		// - Retrieve sub model values and compare to expected values
-		assertTrue(subModel.getIdShort().equals("sm-001"));
-		assertTrue(subModel.getProperties().get("prop1").getIdShort().equals("prop1"));
-		assertTrue((int) subModel.getProperties().get("prop1").get() == 234);
-		assertTrue((int) subModel.getProperties().get("prop3").get() == 17);
-		assertTrue(subModel.getSubmodelElements().get("prop2").getIdShort().equals("prop2"));
-		assertTrue((int) ((ISubmodelElementCollection) subModel.getSubmodelElements().get("prop2")).getProperties().get("prop11").get() == 123);
-
-
-		// Connect to sub model using lower-level VAB interface
-		VABElementProxy connSubModel1 = this.connManager.connectToVABElement("sm-001VAB");
-		// - Read property values and compare with expected values
-		assertTrue((int) ((Map<String, Object>) connSubModel1.getModelPropertyValue(SubmodelElementProvider.PROPERTIES + "/prop1")).get("value") == 234);
-		assertTrue((int) ((Map<String, Object>) connSubModel1.getModelPropertyValue(SubmodelElementProvider.PROPERTIES + "/prop3")).get("value") == 17);
-		assertTrue(((Map<String, Object>) connSubModel1.getModelPropertyValue(SubmodelElementProvider.PROPERTIES + "/prop1")).get("idShort").equals("prop1"));
-		assertTrue(((Map<String, Object>) connSubModel1.getModelPropertyValue(SubmodelElementProvider.PROPERTIES + "/prop2")).get("idShort").equals("prop2"));
-		assertTrue((int) ((Map<String, Object>) connSubModel1.getModelPropertyValue("submodelElements/prop2/prop11")).get("value") == 123);
-		// - Change property value using VAB primitive
-		connSubModel1.setModelPropertyValue(SubmodelElementProvider.PROPERTIES + "/prop1/value", 456);
-		// - Read value back using VAB primitive
-		assertTrue((int) ((Map<String, Object>) connSubModel1.getModelPropertyValue(SubmodelElementProvider.PROPERTIES + "/prop1")).get("value") == 456);
-
-		// Read changed value back using SDK connector
-		assertTrue((int) subModel.getProperties().get("prop1").get() == 456);
-	}
-}
-
-
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/connection/servlet/AASSubModelServletConnectorConnection.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/connection/servlet/AASSubModelServletConnectorConnection.java
deleted file mode 100644
index d3f4e0e..0000000
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/connection/servlet/AASSubModelServletConnectorConnection.java
+++ /dev/null
@@ -1,133 +0,0 @@
-package org.eclipse.basyx.examples.snippets.undoc.aas.connection.servlet;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import java.util.Map;
-
-import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
-import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
-import org.eclipse.basyx.components.servlet.submodel.SubmodelServlet;
-import org.eclipse.basyx.examples.contexts.BaSyxExamplesContext_Empty;
-import org.eclipse.basyx.examples.deployment.BaSyxDeployment;
-import org.eclipse.basyx.examples.support.directory.ExampleAASRegistry;
-import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
-import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
-import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElementCollection;
-import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.vab.manager.VABConnectionManager;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
-import org.junit.ClassRule;
-import org.junit.Test;
-
-
-
-/**
- * Export sub model through a servlet and connect to that servlet
- * 
- * @author kuhn
- *
- */
-public class AASSubModelServletConnectorConnection {
-
-	
-	/**
-	 * Example sub model. This example sub model is created with the BaSyx SDK factory and defines the AAS meta model properties
-	 */
-	static class SampleSubModel extends SubModel {
-		/**
-		 * Constructor - create sub model property
-		 */
-		@SuppressWarnings("unchecked")
-		public SampleSubModel() {
-			// Set sub model ID
-			setIdShort("sm-001");
-
-			// Add example properties
-			// - Add simple property
-			Property prop1 = new Property(234);
-			prop1.setIdShort("prop1");
-			addSubModelElement(prop1);
-
-			Property prop11 = new Property(123);
-			prop11.setIdShort("prop11");
-			// - Add container property that holds other properties
-			SubmodelElementCollection container = new SubmodelElementCollection();
-			container.setIdShort("prop2");
-			container.addElement(prop11);
-			// - Add container to property map
-			addSubModelElement(container);
-
-			// Add another property manually to sub model container "properties"
-			Property prop3 = new Property(17);
-			prop3.setIdShort("prop3");
-			{
-				((Map<String, Object>) this.get("submodelElements")).put("prop3", prop3);
-			}
-		}
-	}
-	
-	/**
-	 * Create manager using the directory stub an the HTTPConnectorProvider
-	 */
-	ConnectedAssetAdministrationShellManager manager = new ConnectedAssetAdministrationShellManager(
-			// Add example specific mappings
-			new ExampleAASRegistry()
-			    // - SDK connectors encapsulate relative path to sub model (/aas/submodels/sm-001)
-					.addAASMapping("aas-001", "") // No AAS is provided in this example
-					.addSubmodelMapping("aas-001", "sm-001", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/SampleModel"),
-			// We connect via HTTP
-			new HTTPConnectorProvider());
-
-	/**
-	 * VAB connection manager backend
-	 */
-	protected VABConnectionManager connManager = new VABConnectionManager(
-			// Add example specific mappings
-			new ExamplesPreconfiguredDirectory()
-			    // - VAB needs to know the relative path of the sub model that is defined by AAS meta model
-			    .addMapping("sm-001VAB",  "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/SampleModel/aas/submodels/sm-001"),
-			// We connect via HTTP
-			new HTTPConnectorProvider());
-
-	
-	
-	/**
-	 * Instantiate and start context elements for this example. BaSyxDeployment contexts instantiate all
-	 * components on the IP address of the host. Therefore, all components use the same IP address. 
-	 */
-	@ClassRule
-	public static BaSyxDeployment context = new BaSyxDeployment(
-				// Servlets for example snippet
-				new BaSyxExamplesContext_Empty().
-					// Deploy example specific servlets to Tomcat server in this context
-					addServletMapping("/Testsuite/components/BaSys/1.0/SampleModel/*",       new SubmodelServlet(new SampleSubModel()))
-			);
-
-	
-	/**
-	 * Application code: Connect to sub model, query, and set property values
-	 */
-	@Test
-	public void accessSubModel() throws Exception {
-		
-		// Create and connect SDK connector
-		ISubModel subModel = manager.retrieveSubModel(new ModelUrn("aas-001"), new ModelUrn("sm-001"));
-		
-		// - Retrieve sub model values and compare to expected values
-		assertTrue(subModel.getIdShort().equals("sm-001"));
-		assertTrue(subModel.getProperties().get("prop1").getIdShort().equals("prop1"));
-		assertTrue((int) subModel.getProperties().get("prop1").get() == 234);
-		assertTrue((int) subModel.getProperties().get("prop3").get() == 17);
-
-		ISubmodelElementCollection prop2 = (ISubmodelElementCollection) subModel.getSubmodelElements().get("prop2");
-		assertEquals("prop2", prop2.getIdShort());
-		Map<String, IProperty> properties = prop2.getProperties();
-		assertEquals(123, properties.get("prop11").get());
-	}
-}
-
-
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/connection/servlet/AASSubModelServletVABConnection.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/connection/servlet/AASSubModelServletVABConnection.java
deleted file mode 100644
index 6138225..0000000
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/connection/servlet/AASSubModelServletVABConnection.java
+++ /dev/null
@@ -1,118 +0,0 @@
-package org.eclipse.basyx.examples.snippets.undoc.aas.connection.servlet;
-
-import static org.junit.Assert.assertTrue;
-
-import java.util.Map;
-
-import org.eclipse.basyx.components.servlet.submodel.SubmodelServlet;
-import org.eclipse.basyx.examples.contexts.BaSyxExamplesContext_Empty;
-import org.eclipse.basyx.examples.deployment.BaSyxDeployment;
-import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
-import org.eclipse.basyx.vab.manager.VABConnectionManager;
-import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
-import org.junit.ClassRule;
-import org.junit.Test;
-
-
-
-/**
- * Export sub model through a servlet and connect to that servlet
- * 
- * @author kuhn
- *
- */
-public class AASSubModelServletVABConnection {
-
-	
-	/**
-	 * Example sub model. This example sub model is created with the BaSyx SDK factory and defines the AAS meta model properties
-	 */
-	static class SampleSubModel extends SubModel {
-		/**
-		 * Constructor - create sub model property
-		 */
-		@SuppressWarnings("unchecked")
-		public SampleSubModel() {
-			// Set sub model ID
-			setIdShort("sm-001");
-
-			// Add example properties
-			// - Add simple property
-			Property prop1 = new Property(234);
-			prop1.setIdShort("prop1");
-			addSubModelElement(prop1);
-
-			Property prop11 = new Property(123);
-			prop11.setIdShort("prop11");
-			// - Add container property that holds other properties
-			SubmodelElementCollection container = new SubmodelElementCollection();
-			container.setIdShort("prop2");
-			container.addElement(prop11);
-			// - Add container to property map
-			addSubModelElement(container);
-
-			// Add another property manually to sub model container "properties"
-			Property prop3 = new Property(17);
-			prop3.setIdShort("prop3");
-			{
-				((Map<String, Object>) this.get("submodelElements")).put("prop3", prop3);
-			}
-		}
-	}
-	
-	
-	
-	/**
-	 * VAB connection manager backend
-	 */
-	protected VABConnectionManager connManager = new VABConnectionManager(
-			// Add example specific mappings
-			new ExamplesPreconfiguredDirectory()
-					// Entries map directly at the SubmodelServlet
-				.addMapping("aas-001",    "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/SampleModel")
-			    .addMapping("sm-001",     "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/SampleModel")
-			    .addMapping("sm-001VAB",  "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/SampleModel"),
-			// We connect via HTTP
-			new HTTPConnectorProvider());
-
-	
-	
-	/**
-	 * Instantiate and start context elements for this example. BaSyxDeployment contexts instantiate all
-	 * components on the IP address of the host. Therefore, all components use the same IP address. 
-	 */
-	@ClassRule
-	public static BaSyxDeployment context = new BaSyxDeployment(
-				// Servlets for example snippet
-				new BaSyxExamplesContext_Empty().
-					// Deploy example specific servlets to Tomcat server in this context
-					addServletMapping("/Testsuite/components/BaSys/1.0/SampleModel/*",       new SubmodelServlet(new SampleSubModel()))
-			);
-
-	
-	/**
-	 * Connect to sub model, query, and set property values
-	 */
-	@Test @SuppressWarnings("unchecked")
-	public void accessSubModel() throws Exception {
-		// Connect to sub model using lower-level VAB interface
-		VABElementProxy connSubModel1 = this.connManager.connectToVABElement("sm-001VAB");
-		// - Read property values and compare with expected values
-		assertTrue((int) ((Map<String, Object>) connSubModel1.getModelPropertyValue(SubmodelElementProvider.PROPERTIES + "/prop1")).get("value") == 234);
-		assertTrue((int) ((Map<String, Object>) connSubModel1.getModelPropertyValue(SubmodelElementProvider.PROPERTIES + "/prop3")).get("value") == 17);
-		assertTrue(((Map<String, Object>) connSubModel1.getModelPropertyValue(SubmodelElementProvider.PROPERTIES + "/prop1")).get("idShort").equals("prop1"));
-		assertTrue(((Map<String, Object>) connSubModel1.getModelPropertyValue(SubmodelElementProvider.PROPERTIES + "/prop2")).get("idShort").equals("prop2"));
-		assertTrue((int) ((Map<String, Object>) connSubModel1.getModelPropertyValue("submodelElements/prop2/prop11/value")).get("value") == 123);
-		// - Change property value using VAB primitive
-		connSubModel1.setModelPropertyValue(SubmodelElementProvider.PROPERTIES + "/prop1/value", 456);
-		// - Read value back using VAB primitive
-		assertTrue((int) ((Map<String, Object>) connSubModel1.getModelPropertyValue(SubmodelElementProvider.PROPERTIES + "/prop1/value")).get("value") == 456);
-	}
-}
-
-
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/dynamic/RunAASDynamicOperationSnippet.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/dynamic/RunAASDynamicOperationSnippet.java
deleted file mode 100644
index cd59adf..0000000
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/dynamic/RunAASDynamicOperationSnippet.java
+++ /dev/null
@@ -1,106 +0,0 @@
-package org.eclipse.basyx.examples.snippets.undoc.aas.dynamic;
-
-import static org.junit.Assert.assertTrue;
-
-import java.io.Serializable;
-import java.util.Map;
-import java.util.function.Supplier;
-
-import org.eclipse.basyx.components.servlet.vab.VABLambdaServlet;
-import org.eclipse.basyx.examples.TestContext;
-import org.eclipse.basyx.examples.deployment.BaSyxDeployment;
-import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.vab.manager.VABConnectionManager;
-import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
-import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaProviderHelper;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
-import org.junit.ClassRule;
-import org.junit.Test;
-
-
-
-/**
- * Illustrate the dynamic deployment of AAS operations
- * 
- * @author kuhn
- *
- */
-public class RunAASDynamicOperationSnippet {
-
-	
-	/**
-	 * VAB connection manager backend
-	 */
-	protected VABConnectionManager connManager = new VABConnectionManager(
-			new ExamplesPreconfiguredDirectory()
-				// Add example specific mappings
-			    .addMapping("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003",  "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/devicestatusVAB/"),
-			new HTTPConnectorProvider());
-
-	
-	/**
-	 * Instantiate and start context elements for this example. BaSyxDeployment contexts instantiate all
-	 * components on the IP address of the host. Therefore, all components use the same IP address. 
-	 */
-	@ClassRule
-	public static BaSyxDeployment context = new BaSyxDeployment(
-				// Simulated servlets
-				// - BaSys topology with one AAS Server and one SQL directory
-				TestContext.sqlContext.
-					// Deploy example specific servlets to Tomcat server in this context
-					addServletMapping("/Testsuite/components/BaSys/1.0/devicestatusVAB/*", new VABLambdaServlet())
-			);
-
-	
-	
-	
-	/**
-	 * Test basic queries
-	 */
-	@Test
-	public void snippet() throws Exception {
-
-		// Server connections
-		// - Connect to device (VAB object)
-		VABElementProxy connSubModel1 = this.connManager.connectToVABElement("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003");
-
-		
-		// Create properties on AAS
-
-		// - Add example properties
-		SubModel submodel = new SubModel();
-		submodel.setIdShort("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003");
-		Property prop1 = new Property(7);
-		prop1.setIdShort("prop1");
-		submodel.addSubModelElement(prop1);
-
-		Property prop2 = new Property("myStr");
-		prop2.setIdShort("prop2");
-		submodel.addSubModelElement(prop2);
-		// - Transfer sub model to server
-		connSubModel1.setModelPropertyValue("/", submodel);
-
-		
-		// Read property values
-		String prop2Val = (String) connSubModel1.getModelPropertyValue("submodelElements/prop2/value");
-		// - Check property values
-		assertTrue(prop2Val.equals("myStr"));
-
-		
-		// Create dynamic get/set operation as lambda expression
-		Map<String, Object> dynamicPropertyVal = VABLambdaProviderHelper.createSimple((Supplier<Object> & Serializable) () -> {
-			return "dynamicExampleValue";
-		}, null);
-		// - Update property properties/dynamicExample with dynamic get/set operation
-		connSubModel1.setModelPropertyValue("submodelElements/prop2/value", dynamicPropertyVal);
-
-		
-		// Read dynamicExample property
-		prop2Val = (String) connSubModel1.getModelPropertyValue("submodelElements/prop2/value");
-		// - Check property values
-		assertTrue(prop2Val.equals("dynamicExampleValue"));
-	}
-}
-
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/dynamic/RunAASManualHTTPOperationsSnippet.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/dynamic/RunAASManualHTTPOperationsSnippet.java
deleted file mode 100644
index 8da4b52..0000000
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/dynamic/RunAASManualHTTPOperationsSnippet.java
+++ /dev/null
@@ -1,99 +0,0 @@
-package org.eclipse.basyx.examples.snippets.undoc.aas.dynamic;
-
-import static org.junit.Assert.assertEquals;
-
-import java.util.Map;
-
-import org.eclipse.basyx.components.servlet.vab.VABLambdaServlet;
-import org.eclipse.basyx.examples.TestContext;
-import org.eclipse.basyx.examples.deployment.BaSyxDeployment;
-import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.tools.webserviceclient.WebServiceJSONClient;
-import org.eclipse.basyx.vab.manager.VABConnectionManager;
-import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
-import org.junit.ClassRule;
-import org.junit.Test;
-
-
-
-/**
- * Illustrate the use of AAS operations using HTTP REST calls
- * 
- * @author kuhn
- *
- */
-public class RunAASManualHTTPOperationsSnippet {
-
-	
-	/**
-	 * VAB connection manager backend
-	 */
-	protected VABConnectionManager connManager = new VABConnectionManager(
-			new ExamplesPreconfiguredDirectory()
-				// Add example specific mappings
-			    .addMapping("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003",  "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/devicestatusVAB/"),
-			new HTTPConnectorProvider());
-
-	
-	/**
-	 * Instantiate and start context elements for this example. BaSyxDeployment contexts instantiate all
-	 * components on the IP address of the host. Therefore, all components use the same IP address. 
-	 */
-	@ClassRule
-	public static BaSyxDeployment context = new BaSyxDeployment(
-				// Simulated servlets
-				// - BaSys topology with one AAS Server and one SQL directory
-				TestContext.sqlContext.
-					// Deploy example specific servlets to Tomcat server in this context
-					addServletMapping("/Testsuite/components/BaSys/1.0/devicestatusVAB/*", new VABLambdaServlet())
-			);
-
-	
-	
-	
-	/**
-	 * Test basic queries
-	 */
-	@Test @SuppressWarnings("unchecked")
-	public void snippet() throws Exception {
-
-		// Server connections
-		// - Connect to device (VAB object)
-		VABElementProxy connSubModel1 = this.connManager.connectToVABElement("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003");
-
-		int prop1Val = 7;
-		String prop1IdShort = "prop1";
-		String prop2Val = "myStr";
-		// Add example properties
-		SubModel submodel = new SubModel();
-		submodel.setIdShort("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003");
-		Property prop1 = new Property(prop1Val);
-		prop1.setIdShort(prop1IdShort);
-		submodel.addSubModelElement(prop1);
-
-		Property prop2 = new Property(prop2Val);
-		prop2.setIdShort("prop2");
-		submodel.addSubModelElement(prop2);
-
-		// Transfer sub model to server
-		connSubModel1.setModelPropertyValue("/", submodel);
-		
-		// Web service client accesses AAS using HTTP REST calls
-		WebServiceJSONClient jsonClient = new WebServiceJSONClient();
-		
-		// Read property values
-		// - Use WebServiceJSONClient class. Returned property contains meta data. The actual property is stored in property "entity", property value is in entity property "value"
-		int retrievedProp1Val = (int) ((Map<String, Object>) jsonClient.get("http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/devicestatusVAB/submodelElements/prop1")).get("value");
-		String retrievedProp1Id = (String) ((Map<String, Object>) jsonClient.get("http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/devicestatusVAB/submodelElements/prop1")).get("idShort");
-		String retrievedProp2Val = (String) ((Map<String, Object>) jsonClient.get("http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/devicestatusVAB/submodelElements/prop2")).get("value");
-		
-		// Check results
-		assertEquals(prop1Val, retrievedProp1Val);
-		assertEquals(prop1IdShort, retrievedProp1Id);
-		assertEquals(prop2Val, retrievedProp2Val);
-	}
-}
-
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/dynamic/RunAASPropertiesCRUDAccessSnippet.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/dynamic/RunAASPropertiesCRUDAccessSnippet.java
deleted file mode 100644
index 74adbfa..0000000
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/dynamic/RunAASPropertiesCRUDAccessSnippet.java
+++ /dev/null
@@ -1,114 +0,0 @@
-package org.eclipse.basyx.examples.snippets.undoc.aas.dynamic;
-
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import org.eclipse.basyx.components.servlet.vab.VABLambdaServlet;
-import org.eclipse.basyx.examples.TestContext;
-import org.eclipse.basyx.examples.deployment.BaSyxDeployment;
-import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
-import org.eclipse.basyx.vab.manager.VABConnectionManager;
-import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
-import org.junit.ClassRule;
-import org.junit.Test;
-
-
-
-/**
- * Illustrate the use of AAS operations
- * 
- * @author kuhn
- *
- */
-public class RunAASPropertiesCRUDAccessSnippet {
-
-	
-	/**
-	 * VAB connection manager backend
-	 */
-	protected VABConnectionManager connManager = new VABConnectionManager(
-			new ExamplesPreconfiguredDirectory()
-				// Add example specific mappings
-			    .addMapping("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003",  "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/devicestatusVAB/"),
-			new HTTPConnectorProvider());
-
-	
-	/**
-	 * Instantiate and start context elements for this example. BaSyxDeployment contexts instantiate all
-	 * components on the IP address of the host. Therefore, all components use the same IP address. 
-	 */
-	@ClassRule
-	public static BaSyxDeployment context = new BaSyxDeployment(
-				// Simulated servlets
-				// - BaSys topology with one AAS Server and one SQL directory
-				TestContext.sqlContext.
-					// Deploy example specific servlets to Tomcat server in this context
-					addServletMapping("/Testsuite/components/BaSys/1.0/devicestatusVAB/*", new VABLambdaServlet())
-			);
-
-	
-	
-	
-	/**
-	 * Test basic queries
-	 */
-	@Test
-	public void snippet() throws Exception {
-
-		// Server connections
-		// - Connect to device (VAB object)
-		VABElementProxy connSubModel1 = this.connManager.connectToVABElement("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003");
-
-		
-		// Create properties on AAS
-		// - Add example properties
-		SubModel submodel = new SubModel();
-		submodel.setIdShort("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003");
-		Property prop1 = new Property(7);
-		prop1.setIdShort("prop1");
-		submodel.addSubModelElement(prop1);
-
-		Property prop2 = new Property("myStr");
-		prop2.setIdShort("prop2");
-		submodel.addSubModelElement(prop2);
-		// - Transfer sub model to server
-		connSubModel1.setModelPropertyValue("/", submodel);
-		
-		// Read property values
-		int prop1Val = (int) connSubModel1.getModelPropertyValue("submodelElements/prop1/value");
-		String prop2Val = (String) connSubModel1.getModelPropertyValue("submodelElements/prop2/value");
-		// - Check property values
-		assertTrue(prop1Val == 7);
-		assertTrue(prop2Val.equals("myStr"));
-		
-		// Update property values
-		connSubModel1.setModelPropertyValue("submodelElements/prop1/value", 8);
-		connSubModel1.setModelPropertyValue("submodelElements/prop2/value", "stillMine");
-		
-		// Read property values again
-		prop1Val = (int) connSubModel1.getModelPropertyValue("submodelElements/prop1/value");
-		prop2Val = (String) connSubModel1.getModelPropertyValue("submodelElements/prop2/value");
-		// - Check property values
-		assertTrue(prop1Val == 8);
-		assertTrue(prop2Val.equals("stillMine"));
-
-		// Delete property values
-		connSubModel1.deleteValue("submodelElements/prop1");
-		connSubModel1.deleteValue("submodelElements/prop2");
-		
-		// Read property values again
-		try {
-			connSubModel1.getModelPropertyValue("submodelElements/prop1");
-			fail();
-		} catch (ResourceNotFoundException e) {}
-		try {
-			connSubModel1.getModelPropertyValue("submodelElements/prop2");
-			fail();
-		} catch (ResourceNotFoundException e) {}
-	}
-}
-
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/dynamic/RunAASTailoredSupplierSnippet.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/dynamic/RunAASTailoredSupplierSnippet.java
deleted file mode 100644
index 379a696..0000000
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/dynamic/RunAASTailoredSupplierSnippet.java
+++ /dev/null
@@ -1,141 +0,0 @@
-package org.eclipse.basyx.examples.snippets.undoc.aas.dynamic;
-
-import static org.junit.Assert.assertTrue;
-
-import java.io.Serializable;
-import java.util.Map;
-import java.util.function.Supplier;
-
-import org.eclipse.basyx.components.servlet.vab.VABLambdaServlet;
-import org.eclipse.basyx.examples.TestContext;
-import org.eclipse.basyx.examples.deployment.BaSyxDeployment;
-import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.vab.manager.VABConnectionManager;
-import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
-import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaProviderHelper;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
-import org.junit.ClassRule;
-import org.junit.Test;
-
-
-
-/**
- * Example for a tailored BaSyx supplier
- * 
- * - BaSyx will serialize this class (and all contained references) and transmit it to the AAS server
- * 
- * @author kuhn
- *
- */
-class TailoredBaSyxSupplier implements Supplier<Object>, Serializable {
-
-	/**
-	 * Version number of serialized instances
-	 */
-	private static final long serialVersionUID = 1L;
-
-
-	/**
-	 * Return value
-	 */
-	@Override
-	public Object get() {
-		// Delegate call to tailored BaSyx supplier base class
-		return getInternal();
-	}
-
-	
-	/**
-	 * Example function of tailored BaSyx supplier base class
-	 */
-	protected String getInternal() {
-		return "BaSyxSupplier!";
-	}
-}
-
-
-
-
-/**
- * Illustrate the dynamic deployment of AAS operations with a tailored consumer
- * 
- * @author kuhn
- *
- */
-public class RunAASTailoredSupplierSnippet {
-
-	
-	/**
-	 * VAB connection manager backend
-	 */
-	protected VABConnectionManager connManager = new VABConnectionManager(
-			new ExamplesPreconfiguredDirectory()
-				// Add example specific mappings
-			    .addMapping("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003",  "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/devicestatusVAB/"),
-			new HTTPConnectorProvider());
-
-	
-	/**
-	 * Instantiate and start context elements for this example. BaSyxDeployment contexts instantiate all
-	 * components on the IP address of the host. Therefore, all components use the same IP address. 
-	 */
-	@ClassRule
-	public static BaSyxDeployment context = new BaSyxDeployment(
-				// Simulated servlets
-				// - BaSys topology with one AAS Server and one SQL directory
-				TestContext.sqlContext.
-					// Deploy example specific servlets to Tomcat server in this context
-					addServletMapping("/Testsuite/components/BaSys/1.0/devicestatusVAB/*", new VABLambdaServlet())
-			);
-
-		
-	
-	/**
-	 * Test basic queries
-	 */
-	@Test
-	public void snippet() throws Exception {
-
-		// Server connections
-		// - Connect to device (VAB object)
-		VABElementProxy connSubModel1 = this.connManager.connectToVABElement("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003");
-
-		
-		// Create properties on AAS
-
-		// - Add example properties
-		SubModel submodel = new SubModel();
-		submodel.setIdShort("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003");
-		Property prop1 = new Property(7);
-		prop1.setIdShort("prop1");
-		submodel.addSubModelElement(prop1);
-
-		Property prop2 = new Property("myStr");
-		prop2.setIdShort("prop2");
-		submodel.addSubModelElement(prop2);
-
-		// - Transfer sub model to server
-		connSubModel1.setModelPropertyValue("/", submodel);
-
-		
-		// Read property values
-		String prop2Val = (String) connSubModel1.getModelPropertyValue("submodelElements/prop2/value");
-		// - Check property values
-		assertTrue(prop2Val.equals("myStr"));
-
-		
-		// Create dynamic get/set operation as lambda expression
-		Map<String, Object> dynamicPropertyVal = VABLambdaProviderHelper.createSimple(new TailoredBaSyxSupplier(), null);
-		// - Update property properties/dynamicExample with dynamic get/set operation
-		connSubModel1.setModelPropertyValue("submodelElements/prop2/value", dynamicPropertyVal);
-
-		// Read dynamicExample property
-		prop2Val = (String) connSubModel1.getModelPropertyValue("submodelElements/prop2/value");
-
-		// - Check value
-		assertTrue(prop2Val.equals("BaSyxSupplier!"));
-	}
-}
-
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/vab/connection/RunAASManualHTTPOperationsSnippet.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/vab/connection/RunAASManualHTTPOperationsSnippet.java
deleted file mode 100644
index 3fb38c5..0000000
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/vab/connection/RunAASManualHTTPOperationsSnippet.java
+++ /dev/null
@@ -1,81 +0,0 @@
-package org.eclipse.basyx.examples.snippets.undoc.vab.connection;
-
-import static org.junit.Assert.assertEquals;
-
-import java.util.HashMap;
-
-import org.eclipse.basyx.components.servlet.vab.VABLambdaServlet;
-import org.eclipse.basyx.examples.TestContext;
-import org.eclipse.basyx.examples.deployment.BaSyxDeployment;
-import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
-import org.eclipse.basyx.tools.webserviceclient.WebServiceJSONClient;
-import org.eclipse.basyx.vab.manager.VABConnectionManager;
-import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
-import org.junit.ClassRule;
-
-
-
-/**
- * Illustrate the use of AAS operations using HTTP REST calls
- * 
- * @author kuhn
- *
- */
-public class RunAASManualHTTPOperationsSnippet {
-
-	
-	/**
-	 * VAB connection manager backend
-	 */
-	protected VABConnectionManager connManager = new VABConnectionManager(
-			new ExamplesPreconfiguredDirectory()
-				// Add example specific mappings
-			    .addMapping("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003",  "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/devicestatusVAB/"),
-			new HTTPConnectorProvider());
-
-	
-	/**
-	 * Instantiate and start context elements for this example. BaSyxDeployment contexts instantiate all
-	 * components on the IP address of the host. Therefore, all components use the same IP address. 
-	 */
-	@ClassRule
-	public static BaSyxDeployment context = new BaSyxDeployment(
-				// Simulated servlets
-				// - BaSys topology with one AAS Server and one SQL directory
-				TestContext.sqlContext.
-					// Deploy example specific servlets to Tomcat server in this context
-					addServletMapping("/Testsuite/components/BaSys/1.0/devicestatusVAB/*", new VABLambdaServlet())
-			);
-
-	
-	
-	
-	/**
-	 * Test basic queries
-	 */
-	public void snippet() throws Exception {
-
-		// Server connections
-		// - Connect to device (VAB object)
-		VABElementProxy connSubModel1 = this.connManager.connectToVABElement("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003");
-
-		int prop1Val = 7;
-		String prop2Val = "myStr";
-		// Create properties on AAS using connection
-		connSubModel1.createValue("properties", new HashMap<String, Object>());
-		connSubModel1.createValue("properties/prop1", prop1Val);
-		connSubModel1.createValue("properties/prop2", prop2Val);
-		
-		
-		// Web service client accesses AAS using HTTP REST calls
-		WebServiceJSONClient jsonClient = new WebServiceJSONClient();
-		
-		
-		// Read property values
-		// - Use WebServiceJSONClient class. Returned property contains meta data. The actual value is stored in property "entity"
-		assertEquals(prop1Val, jsonClient.get("http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/devicestatusVAB/properties/prop1"));
-		assertEquals(prop2Val, jsonClient.get("http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/devicestatusVAB/properties/prop2"));
-	}
-}
-
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/vab/connection/RunAASPropertiesSnippet.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/vab/connection/RunAASPropertiesSnippet.java
deleted file mode 100644
index ed3a544..0000000
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/vab/connection/RunAASPropertiesSnippet.java
+++ /dev/null
@@ -1,99 +0,0 @@
-package org.eclipse.basyx.examples.snippets.undoc.vab.connection;
-
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.util.HashMap;
-
-import org.eclipse.basyx.components.servlet.vab.VABLambdaServlet;
-import org.eclipse.basyx.examples.TestContext;
-import org.eclipse.basyx.examples.deployment.BaSyxDeployment;
-import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
-import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
-import org.eclipse.basyx.vab.manager.VABConnectionManager;
-import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
-import org.junit.ClassRule;
-import org.junit.Test;
-
-
-
-/**
- * Illustrate the use of AAS operations
- * 
- * @author kuhn
- *
- */
-public class RunAASPropertiesSnippet {
-
-	
-	/**
-	 * VAB connection manager backend
-	 */
-	protected VABConnectionManager connManager = new VABConnectionManager(
-			new ExamplesPreconfiguredDirectory()
-				// Add example specific mappings
-			    .addMapping("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003",  "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/devicestatusVAB/"),
-			new HTTPConnectorProvider());
-
-	
-	/**
-	 * Instantiate and start context elements for this example. BaSyxDeployment contexts instantiate all
-	 * components on the IP address of the host. Therefore, all components use the same IP address. 
-	 */
-	@ClassRule
-	public static BaSyxDeployment context = new BaSyxDeployment(
-				// Simulated servlets
-				// - BaSys topology with one AAS Server and one SQL directory
-				TestContext.sqlContext.
-					// Deploy example specific servlets to Tomcat server in this context
-					addServletMapping("/Testsuite/components/BaSys/1.0/devicestatusVAB/*", new VABLambdaServlet())
-			);
-
-	
-	
-	
-	/**
-	 * Test basic queries
-	 */
-	@Test
-	public void snippet() throws Exception {
-
-		// Server connections
-		// - Connect to device (VAB object)
-		VABElementProxy connSubModel1 = this.connManager.connectToVABElement("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003");
-
-		
-		// Create properties on AAS
-		connSubModel1.createValue("properties", new HashMap<String, Object>());
-		connSubModel1.createValue("properties/prop1", 7);
-		connSubModel1.createValue("properties/prop2", "myStr");
-		
-		// Read property values
-		assertTrue((int) connSubModel1.getModelPropertyValue("properties/prop1") == 7);
-		assertTrue(connSubModel1.getModelPropertyValue("properties/prop2").equals("myStr"));
-		
-		// Update property values
-		connSubModel1.setModelPropertyValue("properties/prop1", 8);
-		connSubModel1.setModelPropertyValue("properties/prop2", "stillMine");
-		
-		// Read property values again
-		assertTrue((int) connSubModel1.getModelPropertyValue("properties/prop1") == 8);
-		assertTrue(connSubModel1.getModelPropertyValue("properties/prop2").equals("stillMine"));
-
-		// Delete property values
-		connSubModel1.deleteValue("properties/prop1");
-		connSubModel1.deleteValue("properties/prop2");
-		
-		// Read property values again
-		try {
-			connSubModel1.getModelPropertyValue("properties/prop1");
-			fail();
-		} catch (ResourceNotFoundException e) {}
-		try {
-			connSubModel1.getModelPropertyValue("properties/prop2");
-			fail();
-		} catch (ResourceNotFoundException e) {}
-	}
-}
-
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/urn/ConstructURNs.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/urn/ConstructURNs.java
index 7ec783a..807b3df 100644
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/urn/ConstructURNs.java
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/urn/ConstructURNs.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.examples.snippets.urn;
 
 import static org.junit.Assert.assertTrue;
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/vab/CRUDOperations.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/vab/CRUDOperations.java
index d9636b4..3c1e831 100644
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/vab/CRUDOperations.java
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/vab/CRUDOperations.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.examples.snippets.vab;
 
 import static org.junit.Assert.assertTrue;
@@ -6,13 +15,13 @@
 import java.util.HashMap;
 
 import org.eclipse.basyx.components.servlet.vab.VABLambdaServlet;
-import org.eclipse.basyx.examples.TestContext;
+import org.eclipse.basyx.examples.contexts.BaSyxExamplesContext;
 import org.eclipse.basyx.examples.deployment.BaSyxDeployment;
 import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
 import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
 import org.eclipse.basyx.vab.manager.VABConnectionManager;
 import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorFactory;
 import org.junit.ClassRule;
 import org.junit.Test;
 
@@ -41,9 +50,9 @@
 			new ExamplesPreconfiguredDirectory()
 				// Add example specific mappings
 			    .addMapping("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003",  "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/devicestatusVAB/"),
-			new HTTPConnectorProvider());
+			new HTTPConnectorFactory());
 
-	
+
 	/**
 	 * The BaSyx Deployment instantiates and starts context elements for this example. 
 	 * 
@@ -57,7 +66,7 @@
 	public static BaSyxDeployment context = new BaSyxDeployment(
 				// Simulated servlets
 				// - BaSys topology with one AAS Server and one SQL directory
-				TestContext.sqlContext.
+				new BaSyxExamplesContext().
 					// Deploy example specific servlets to Tomcat server in this context
 					addServletMapping("/Testsuite/components/BaSys/1.0/devicestatusVAB/*", new VABLambdaServlet())
 			);
@@ -73,7 +82,7 @@
 		// Server connections
 		// - Connect to VAB object by ID. The connection manager looks up this ID in
 		//   its directory
-		VABElementProxy connSubModel1 = this.connManager.connectToVABElement("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003");
+		VABElementProxy connSubmodel1 = this.connManager.connectToVABElement("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003");
 
 		
 		// Create properties on AAS
@@ -81,33 +90,33 @@
 		//   properties "prop1" and "prop2". Container and properties lack the 
 		//   required properties for AAS and AAS sub models. They are therefore
 		//   not compliant to Asset Administration Shells.
-		connSubModel1.createValue("properties", new HashMap<String, Object>());
-		connSubModel1.createValue("properties/prop1", 7);
-		connSubModel1.createValue("properties/prop2", "myStr");
+		connSubmodel1.createValue("properties", new HashMap<String, Object>());
+		connSubmodel1.createValue("properties/prop1", 7);
+		connSubmodel1.createValue("properties/prop2", "myStr");
 		
 		// Read property values
-		int    prop1Val = (int)    connSubModel1.getModelPropertyValue("properties/prop1");
-		String prop2Val = (String) connSubModel1.getModelPropertyValue("properties/prop2");
+		int    prop1Val = (int)    connSubmodel1.getValue("properties/prop1");
+		String prop2Val = (String) connSubmodel1.getValue("properties/prop2");
 		
 		// Update property values
-		connSubModel1.setModelPropertyValue("properties/prop1", 8);
-		connSubModel1.setModelPropertyValue("properties/prop2", "stillMine");
+		connSubmodel1.setValue("properties/prop1", 8);
+		connSubmodel1.setValue("properties/prop2", "stillMine");
 		
 		// Read property values again
-		int    prop1Val_2 = (int)    connSubModel1.getModelPropertyValue("properties/prop1");
-		String prop2Val_2 = (String) connSubModel1.getModelPropertyValue("properties/prop2");
+		int    prop1Val_2 = (int)    connSubmodel1.getValue("properties/prop1");
+		String prop2Val_2 = (String) connSubmodel1.getValue("properties/prop2");
 
 		// Delete property values
-		connSubModel1.deleteValue("properties/prop1");
-		connSubModel1.deleteValue("properties/prop2");
+		connSubmodel1.deleteValue("properties/prop1");
+		connSubmodel1.deleteValue("properties/prop2");
 		
 		// Read property values again
 		try {
-			connSubModel1.getModelPropertyValue("properties/prop1");
+			connSubmodel1.getValue("properties/prop1");
 			fail();
 		} catch (ResourceNotFoundException e) {}
 		try {
-			connSubModel1.getModelPropertyValue("properties/prop2");
+			connSubmodel1.getValue("properties/prop2");
 			fail();
 		} catch (ResourceNotFoundException e) {}
 
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/vab/DynamicPropertyClass.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/vab/DynamicPropertyClass.java
index 7dcbee1..8f6b4b4 100644
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/vab/DynamicPropertyClass.java
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/vab/DynamicPropertyClass.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.examples.snippets.vab;
 
 import static org.junit.Assert.assertTrue;
@@ -7,13 +16,13 @@
 import java.util.function.Supplier;
 
 import org.eclipse.basyx.components.servlet.vab.VABLambdaServlet;
-import org.eclipse.basyx.examples.TestContext;
+import org.eclipse.basyx.examples.contexts.BaSyxExamplesContext;
 import org.eclipse.basyx.examples.deployment.BaSyxDeployment;
 import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
 import org.eclipse.basyx.vab.manager.VABConnectionManager;
 import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
 import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaProviderHelper;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorFactory;
 import org.junit.ClassRule;
 import org.junit.Test;
 
@@ -84,9 +93,9 @@
 			new ExamplesPreconfiguredDirectory()
 				// Add example specific mappings
 			    .addMapping("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003",  "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/devicestatusVAB/"),
-			new HTTPConnectorProvider());
+			new HTTPConnectorFactory());
 
-	
+
 	/**
 	 * The BaSyx Deployment instantiates and starts context elements for this example. 
 	 * 
@@ -100,7 +109,7 @@
 	public static BaSyxDeployment context = new BaSyxDeployment(
 				// Simulated servlets
 				// - BaSys topology with one AAS Server and one SQL directory
-				TestContext.sqlContext.
+				new BaSyxExamplesContext().
 					// Deploy example specific servlets to Tomcat server in this context
 					addServletMapping("/Testsuite/components/BaSys/1.0/devicestatusVAB/*", new VABLambdaServlet())
 			);
@@ -116,17 +125,17 @@
 
 		// Server connections
 		// - Connect to device (VAB object)
-		VABElementProxy connSubModel1 = this.connManager.connectToVABElement("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003");
+		VABElementProxy connSubmodel1 = this.connManager.connectToVABElement("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003");
 
 		
 		// Create dynamic get/set operation. Instantiate class TailoredBaSyxSupplier as getter, 
 		// no setter (null) is provided.
 		Map<String, Object> dynamicPropertyVal = VABLambdaProviderHelper.createSimple(new TailoredBaSyxSupplier(), null);
 		// - Update property properties/dynamicExample with dynamic get/set operation
-		connSubModel1.createValue("dynamicExampleProperty", dynamicPropertyVal);
+		connSubmodel1.createValue("dynamicExampleProperty", dynamicPropertyVal);
 
 		// Read dynamicExample property
-		Object propertyValue = connSubModel1.getModelPropertyValue("dynamicExampleProperty");
+		Object propertyValue = connSubmodel1.getValue("dynamicExampleProperty");
 
 		
 		// Compare returned to expected values
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/vab/DynamicPropertyLambda.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/vab/DynamicPropertyLambda.java
index 9511199..0cc6b92 100644
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/vab/DynamicPropertyLambda.java
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/vab/DynamicPropertyLambda.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.examples.snippets.vab;
 
 import static org.junit.Assert.assertTrue;
@@ -7,13 +16,13 @@
 import java.util.function.Supplier;
 
 import org.eclipse.basyx.components.servlet.vab.VABLambdaServlet;
-import org.eclipse.basyx.examples.TestContext;
+import org.eclipse.basyx.examples.contexts.BaSyxExamplesContext;
 import org.eclipse.basyx.examples.deployment.BaSyxDeployment;
 import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
 import org.eclipse.basyx.vab.manager.VABConnectionManager;
 import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
 import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaProviderHelper;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorFactory;
 import org.junit.ClassRule;
 import org.junit.Test;
 
@@ -35,7 +44,7 @@
  */
 public class DynamicPropertyLambda {
 
-	
+
 	/**
 	 * VAB connection manager backend
 	 * 
@@ -46,7 +55,7 @@
 			new ExamplesPreconfiguredDirectory()
 				// Add example specific mappings
 			    .addMapping("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003",  "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/devicestatusVAB/"),
-			new HTTPConnectorProvider());
+			new HTTPConnectorFactory());
 
 	
 	/**
@@ -62,7 +71,7 @@
 	public static BaSyxDeployment context = new BaSyxDeployment(
 				// Simulated servlets
 				// - BaSys topology with one AAS Server and one SQL directory
-				TestContext.sqlContext.
+				new BaSyxExamplesContext().
 					// Deploy example specific servlets to Tomcat server in this context
 					addServletMapping("/Testsuite/components/BaSys/1.0/devicestatusVAB/*", new VABLambdaServlet())
 			);
@@ -80,7 +89,7 @@
 		// Server connections
 		// - Connect to VAB object by ID. The connection manager looks up this ID in
 		//   its directory
-		VABElementProxy connSubModel1 = this.connManager.connectToVABElement("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003");
+		VABElementProxy connSubmodel1 = this.connManager.connectToVABElement("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003");
 
 		
 		// Create dynamic get/operation as Lambda expression, no set operation (null) is provided.
@@ -88,11 +97,11 @@
 			return "dynamicExampleValue";
 		}, null);
 		// - Update property properties/dynamicExample with dynamic get/set operation
-		connSubModel1.createValue("dynamicExampleProperty", dynamicPropertyVal);
+		connSubmodel1.createValue("dynamicExampleProperty", dynamicPropertyVal);
 
 		// Read dynamicExample property
 		// - This will invoke the previously uploaded Lambda expression
-		Object propertyValue = connSubModel1.getModelPropertyValue("dynamicExampleProperty");
+		Object propertyValue = connSubmodel1.getValue("dynamicExampleProperty");
 		
 		
 		// Compare returned to expected values
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/vab/ManualHTTPCalls.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/vab/ManualHTTPCalls.java
index ed63416..25f2e84 100644
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/vab/ManualHTTPCalls.java
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/vab/ManualHTTPCalls.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.examples.snippets.vab;
 
 import static org.junit.Assert.assertEquals;
@@ -5,13 +14,13 @@
 import java.util.HashMap;
 
 import org.eclipse.basyx.components.servlet.vab.VABLambdaServlet;
-import org.eclipse.basyx.examples.TestContext;
+import org.eclipse.basyx.examples.contexts.BaSyxExamplesContext;
 import org.eclipse.basyx.examples.deployment.BaSyxDeployment;
 import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
 import org.eclipse.basyx.tools.webserviceclient.WebServiceJSONClient;
 import org.eclipse.basyx.vab.manager.VABConnectionManager;
 import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorFactory;
 import org.junit.ClassRule;
 
 /**
@@ -26,7 +35,7 @@
  */
 public class ManualHTTPCalls {
 
-	
+
 	/**
 	 * Create VAB connection manager backend
 	 * 
@@ -37,7 +46,7 @@
 			new ExamplesPreconfiguredDirectory()
 				// Add example specific mappings
 			    .addMapping("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003",  "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/devicestatusVAB/"),
-			new HTTPConnectorProvider());
+			new HTTPConnectorFactory());
 
 	
 	/**
@@ -53,7 +62,7 @@
 	public static BaSyxDeployment context = new BaSyxDeployment(
 				// Simulated servlets
 				// - BaSys topology with one AAS Server and one SQL directory
-				TestContext.sqlContext.
+				new BaSyxExamplesContext().
 					// Deploy example specific servlets to Tomcat server in this context
 					addServletMapping("/Testsuite/components/BaSys/1.0/devicestatusVAB/*", new VABLambdaServlet())
 			);
@@ -70,7 +79,7 @@
 		// Server connections
 		// - Connect to VAB object by ID. The connection manager looks up this ID in
 		//   its directory
-		VABElementProxy connSubModel1 = this.connManager.connectToVABElement("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003");
+		VABElementProxy connSubmodel1 = this.connManager.connectToVABElement("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003");
 
 		int prop1Val = 7;
 		String prop2Val = "myStr";
@@ -79,9 +88,9 @@
 		//   properties "prop1" and "prop2". Container and properties lack the 
 		//   required properties for AAS and AAS sub models. They are therefore
 		//   not compliant to Asset Administration Shells.
-		connSubModel1.createValue("properties", new HashMap<String, Object>());
-		connSubModel1.createValue("properties/prop1", prop1Val);
-		connSubModel1.createValue("properties/prop2", prop2Val);
+		connSubmodel1.createValue("properties", new HashMap<String, Object>());
+		connSubmodel1.createValue("properties/prop1", prop1Val);
+		connSubmodel1.createValue("properties/prop2", prop2Val);
 		
 		
 		// Web service client 
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/vab/provider/FileSystemProviderClass.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/vab/provider/FileSystemProviderClass.java
index 086f3e2..34ad776 100644
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/vab/provider/FileSystemProviderClass.java
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/vab/provider/FileSystemProviderClass.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.examples.snippets.vab.provider;
 
 import static org.junit.Assert.assertEquals;
@@ -47,7 +56,7 @@
 		IModelProvider provider = new FileSystemProvider(fs, basePath, rootElement, true);
 
 		// The interface is equal to the interface used in e.g. the HashMapProvider
-		int previouslyCreated = (Integer) provider.getModelPropertyValue("/myInteger");
+		int previouslyCreated = (Integer) provider.getValue("/myInteger");
 		assertEquals(3, previouslyCreated);
 
 		// When creating elements, the internal directory and file structure represent the changes
@@ -55,7 +64,7 @@
 
 		// Properties are serialized and stored in the file that corresponds to their path
 		String expected = "Max Mustermann";
-		String byProvider = (String) provider.getModelPropertyValue("/name");
+		String byProvider = (String) provider.getValue("/name");
 		String byFileSystem = fs.readFile(basePath + "/name");
 		String byFSDeserialized = (String) gsonTools.deserialize(byFileSystem);
 		assertEquals(expected, byProvider);
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/vab/provider/VABLambdaProviderClass.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/vab/provider/VABLambdaProviderClass.java
index 713f484..714cba5 100644
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/vab/provider/VABLambdaProviderClass.java
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/vab/provider/VABLambdaProviderClass.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.examples.snippets.vab.provider;
 
 import static org.junit.Assert.assertEquals;
@@ -50,17 +59,17 @@
 		IModelProvider provider = new VABLambdaProvider(rootElement);
 
 		// Static and dynamic properties are resolved to their primitive object value
-		assertEquals("myStaticString", provider.getModelPropertyValue("/static"));
-		assertEquals("myDynamicString", provider.getModelPropertyValue("/dynamic"));
+		assertEquals("myStaticString", provider.getValue("/static"));
+		assertEquals("myDynamicString", provider.getValue("/dynamic"));
 
 		// Now each time the dynamic property is read, it resolves its value through the given get operation
 		// - modify the source of the dynamic property
 		dynamicString = "newValue";
 		// - resolve the property
-		assertEquals("newValue", provider.getModelPropertyValue("/dynamic"));
+		assertEquals("newValue", provider.getValue("/dynamic"));
 
 		// The custom setter of the dynamic property in this example only allows string types...
-		provider.setModelPropertyValue("/dynamic", true);
-		assertEquals("newValue", provider.getModelPropertyValue("/dynamic"));
+		provider.setValue("/dynamic", true);
+		assertEquals("newValue", provider.getValue("/dynamic"));
 	}
 }
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/vab/provider/VABMapProviderClass.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/vab/provider/VABMapProviderClass.java
index 92a7188..ee9d103 100644
--- a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/vab/provider/VABMapProviderClass.java
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/vab/provider/VABMapProviderClass.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.examples.snippets.vab.provider;
 
 import static org.junit.Assert.assertEquals;
@@ -48,13 +57,13 @@
 		IModelProvider provider = new VABMapProvider(rootElement);
 
 		// Child elements can now be accessed with a path that is mapped to actual data structure
-		assertEquals("myElement", provider.getModelPropertyValue("/name"));
-		assertEquals("boolean", provider.getModelPropertyValue("/data/type"));
-		assertEquals(true, provider.getModelPropertyValue("/data/value"));
+		assertEquals("myElement", provider.getValue("/name"));
+		assertEquals("boolean", provider.getValue("/data/type"));
+		assertEquals(true, provider.getValue("/data/value"));
 
 		// Future modifications are now applied using the IModelProvider interface.
-		provider.setModelPropertyValue("/name", "yourElement");
-		assertEquals("yourElement", provider.getModelPropertyValue("/name"));
+		provider.setValue("/name", "yourElement");
+		assertEquals("yourElement", provider.getValue("/name"));
 
 		// The creation of nested elements within an existing provider is also possible
 		// HashMaps and Collections are supported for this purpose
@@ -64,6 +73,6 @@
 		provider.createValue("/description", description);
 
 		// The path is again mapped to the HashMap structure
-		assertEquals("This is a generic VAB element", provider.getModelPropertyValue("/description/EN"));
+		assertEquals("This is a generic VAB element", provider.getValue("/description/EN"));
 	}
 }
diff --git a/examples/basys.examples/src/test/resources/registry.properties b/examples/basys.examples/src/test/resources/registry.properties
index 60e38d9..1cdb398 100644
--- a/examples/basys.examples/src/test/resources/registry.properties
+++ b/examples/basys.examples/src/test/resources/registry.properties
@@ -1,43 +1,35 @@
-# ##############################################################
-# Directory configuration file
-# ##############################################################
+# ###############################
+# SQL database configuration file
+# ###############################
+
+# ###############################
+# Credentials
+# ###############################
+# Specifies the credentials for connecting to the SQL database 
+
+dbuser=postgres
+dbpass=admin
+
+# ###############################
+# Database URL
+# ###############################
+# The direct SQL database url for connection
+
+dburl=//localhost:5432/basyx-directory? 
+
+# ###############################
+# SQL driver information
+# ###############################
+# Java Driver and connection prefix for using the driver
+
+sqlDriver=org.postgresql.Driver
+sqlPrefix=jdbc:postgresql:
 
 
+# ###############################
+# Microsoft SQL Server Example
+# ###############################
+# dburl=//localhost:1234;databaseName=mydb
+# sqlDriver=com.microsoft.sqlserver.jdbc.SQLServerDriver
+# sqlPrefix=jdbc:sqlserver:
 
-
-# ##############################################################
-# Directory server configuration
-
-
-# URL and type of uplink server. Forward all requests that we cannot satisfy here to uplink
-# - URL of uplink directory server
-# - Type of uplink server. Currently supported is BASYS (BaSys registry API) or DNS (DNS server processing legalBody tag) 
-cfg.uplink       = 
-cfg.uplink.type  = DNS
-
-
-# Downlink servers, forward matching URI patterns to downlink servers
-# - Match all subunits that end with "is.iese", including "is.iese"
-cfg.downlink.is.pattern   = is.iese
-cfg.downlink.is.directory = http://wherever1
-
-# - Match all subunits that end with "pm.iese", including "pm.iese"
-cfg.downlink.pm.pattern   = pm.iese
-cfg.downlink.pm.directory = http://wherever2
-
-# - Match all subunits that end with ".es.iese", but not "es.iese"
-cfg.downlink.es.pattern   = .es.iese
-cfg.downlink.es.directory = http://wherever3
-
-
-
-
-# ##############################################################
-# SQL database configuration
-
-dbuser             = postgres
-dbpass             = admin
-dburl              = //localhost/basyx-directory?
-
-sqlDriver          = org.postgresql.Driver
-sqlPrefix          = jdbc:postgresql:
diff --git a/examples/basys.registry/.classpath b/examples/basys.registry/.classpath
deleted file mode 100644
index 76b9877..0000000
--- a/examples/basys.registry/.classpath
+++ /dev/null
@@ -1,34 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
-		<attributes>
-			<attribute name="maven.pomderived" value="true"/>
-		</attributes>
-	</classpathentry>
-	<classpathentry kind="con" path="org.eclipse.jst.server.core.container/org.eclipse.jst.server.tomcat.runtimeTarget/Apache Tomcat v8.5">
-		<attributes>
-			<attribute name="owner.project.facets" value="jst.web"/>
-		</attributes>
-	</classpathentry>
-	<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
-		<attributes>
-			<attribute name="maven.pomderived" value="true"/>
-			<attribute name="org.eclipse.jst.component.dependency" value="/WEB-INF/lib"/>
-		</attributes>
-	</classpathentry>
-	<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/5"/>
-	<classpathentry kind="src" output="target/classes" path="src/main/java">
-		<attributes>
-			<attribute name="optional" value="true"/>
-			<attribute name="maven.pomderived" value="true"/>
-		</attributes>
-	</classpathentry>
-	<classpathentry kind="src" output="target/test-classes" path="src/test/java">
-		<attributes>
-			<attribute name="optional" value="true"/>
-			<attribute name="maven.pomderived" value="true"/>
-			<attribute name="test" value="true"/>
-		</attributes>
-	</classpathentry>
-	<classpathentry kind="output" path="target/classes"/>
-</classpath>
diff --git a/examples/basys.registry/.gitignore b/examples/basys.registry/.gitignore
deleted file mode 100644
index f232a6d..0000000
--- a/examples/basys.registry/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-# ignore output 
-target/
-
diff --git a/examples/basys.registry/.project b/examples/basys.registry/.project
deleted file mode 100644
index 63d98e4..0000000
--- a/examples/basys.registry/.project
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>basys.registry</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.jdt.core.javabuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-		<buildCommand>
-			<name>org.eclipse.wst.common.project.facet.core.builder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-		<buildCommand>
-			<name>org.eclipse.wst.validation.validationbuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-		<buildCommand>
-			<name>org.eclipse.m2e.core.maven2Builder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.eclipse.m2e.core.maven2Nature</nature>
-		<nature>org.eclipse.jem.workbench.JavaEMFNature</nature>
-		<nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature>
-		<nature>org.eclipse.wst.common.project.facet.core.nature</nature>
-		<nature>org.eclipse.jdt.core.javanature</nature>
-		<nature>org.eclipse.wst.jsdt.core.jsNature</nature>
-	</natures>
-</projectDescription>
diff --git a/examples/basys.registry/.settings/.jsdtscope b/examples/basys.registry/.settings/.jsdtscope
deleted file mode 100644
index 92e666d..0000000
--- a/examples/basys.registry/.settings/.jsdtscope
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
-	<classpathentry excluding="**/bower_components/*|**/node_modules/*|**/*.min.js" kind="src" path="WebContent"/>
-	<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.JRE_CONTAINER"/>
-	<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.WebProject">
-		<attributes>
-			<attribute name="hide" value="true"/>
-		</attributes>
-	</classpathentry>
-	<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.baseBrowserLibrary"/>
-	<classpathentry kind="output" path=""/>
-</classpath>
diff --git a/examples/basys.registry/.settings/org.eclipse.jdt.core.prefs b/examples/basys.registry/.settings/org.eclipse.jdt.core.prefs
deleted file mode 100644
index 4e4a3ad..0000000
--- a/examples/basys.registry/.settings/org.eclipse.jdt.core.prefs
+++ /dev/null
@@ -1,9 +0,0 @@
-eclipse.preferences.version=1
-org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
-org.eclipse.jdt.core.compiler.compliance=1.8
-org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
-org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
-org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
-org.eclipse.jdt.core.compiler.release=disabled
-org.eclipse.jdt.core.compiler.source=1.8
diff --git a/examples/basys.registry/.settings/org.eclipse.m2e.core.prefs b/examples/basys.registry/.settings/org.eclipse.m2e.core.prefs
deleted file mode 100644
index f897a7f..0000000
--- a/examples/basys.registry/.settings/org.eclipse.m2e.core.prefs
+++ /dev/null
@@ -1,4 +0,0 @@
-activeProfiles=
-eclipse.preferences.version=1
-resolveWorkspaceProjects=true
-version=1
diff --git a/examples/basys.registry/.settings/org.eclipse.wst.common.component b/examples/basys.registry/.settings/org.eclipse.wst.common.component
deleted file mode 100644
index 4d29a2b..0000000
--- a/examples/basys.registry/.settings/org.eclipse.wst.common.component
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?><project-modules id="moduleCoreId" project-version="1.5.0">
-    <wb-module deploy-name="registry-0.0.3-SNAPSHOT">
-        <wb-resource deploy-path="/" source-path="/target/m2e-wtp/web-resources"/>
-        <wb-resource deploy-path="/" source-path="/WebContent" tag="defaultRootSource"/>
-        <wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/java"/>
-        <dependent-module archiveName="basyx.components-0.0.1-SNAPSHOT.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/basyx.components/basyx.components">
-            <dependency-type>uses</dependency-type>
-        </dependent-module>
-        <dependent-module archiveName="basyx.sdk-0.0.1-SNAPSHOT.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/basyx.sdk/basyx.sdk">
-            <dependency-type>uses</dependency-type>
-        </dependent-module>
-        <property name="java-output-path" value="/basys.registry/target/classes"/>
-        <property name="context-root" value="registry"/>
-    </wb-module>
-</project-modules>
diff --git a/examples/basys.registry/.settings/org.eclipse.wst.common.project.facet.core.prefs.xml b/examples/basys.registry/.settings/org.eclipse.wst.common.project.facet.core.prefs.xml
deleted file mode 100644
index cc81385..0000000
--- a/examples/basys.registry/.settings/org.eclipse.wst.common.project.facet.core.prefs.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<root>
-  <facet id="jst.jaxrs">
-    <node name="libprov">
-      <attribute name="provider-id" value="jaxrs-no-op-library-provider"/>
-    </node>
-  </facet>
-</root>
diff --git a/examples/basys.registry/.settings/org.eclipse.wst.common.project.facet.core.xml b/examples/basys.registry/.settings/org.eclipse.wst.common.project.facet.core.xml
deleted file mode 100644
index 5f0749f..0000000
--- a/examples/basys.registry/.settings/org.eclipse.wst.common.project.facet.core.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<faceted-project>
-  <runtime name="Apache Tomcat v8.5"/>
-  <fixed facet="wst.jsdt.web"/>
-  <fixed facet="java"/>
-  <fixed facet="jst.web"/>
-  <installed facet="java" version="1.8"/>
-  <installed facet="jst.web" version="3.1"/>
-  <installed facet="wst.jsdt.web" version="1.0"/>
-  <installed facet="jst.jaxrs" version="2.0"/>
-</faceted-project>
diff --git a/examples/basys.registry/.settings/org.eclipse.wst.jsdt.ui.superType.container b/examples/basys.registry/.settings/org.eclipse.wst.jsdt.ui.superType.container
deleted file mode 100644
index 3bd5d0a..0000000
--- a/examples/basys.registry/.settings/org.eclipse.wst.jsdt.ui.superType.container
+++ /dev/null
@@ -1 +0,0 @@
-org.eclipse.wst.jsdt.launching.baseBrowserLibrary
\ No newline at end of file
diff --git a/examples/basys.registry/.settings/org.eclipse.wst.jsdt.ui.superType.name b/examples/basys.registry/.settings/org.eclipse.wst.jsdt.ui.superType.name
deleted file mode 100644
index 05bd71b..0000000
--- a/examples/basys.registry/.settings/org.eclipse.wst.jsdt.ui.superType.name
+++ /dev/null
@@ -1 +0,0 @@
-Window
\ No newline at end of file
diff --git a/examples/basys.registry/.settings/org.eclipse.wst.validation.prefs b/examples/basys.registry/.settings/org.eclipse.wst.validation.prefs
deleted file mode 100644
index 04cad8c..0000000
--- a/examples/basys.registry/.settings/org.eclipse.wst.validation.prefs
+++ /dev/null
@@ -1,2 +0,0 @@
-disabled=06target
-eclipse.preferences.version=1
diff --git a/examples/basys.registry/Dockerfile b/examples/basys.registry/Dockerfile
deleted file mode 100644
index 11fef4f..0000000
--- a/examples/basys.registry/Dockerfile
+++ /dev/null
@@ -1,8 +0,0 @@
-# Dockerfile
-
-FROM tomcat:8-jdk8
-
-#Copy war file
-COPY target/registry-0.0.3*.war $CATALINA_HOME/webapps/registry.war
-
-CMD /usr/local/tomcat/bin/catalina.sh run && tail -f /usr/local/MYAPP.log
\ No newline at end of file
diff --git a/examples/basys.registry/WebContent/META-INF/MANIFEST.MF b/examples/basys.registry/WebContent/META-INF/MANIFEST.MF
deleted file mode 100644
index 254272e..0000000
--- a/examples/basys.registry/WebContent/META-INF/MANIFEST.MF
+++ /dev/null
@@ -1,3 +0,0 @@
-Manifest-Version: 1.0
-Class-Path: 
-
diff --git a/examples/basys.registry/WebContent/WEB-INF/config/directory/sqldirectory/directory.properties b/examples/basys.registry/WebContent/WEB-INF/config/directory/sqldirectory/directory.properties
deleted file mode 100644
index 1fc05b8..0000000
--- a/examples/basys.registry/WebContent/WEB-INF/config/directory/sqldirectory/directory.properties
+++ /dev/null
@@ -1,45 +0,0 @@
-# ##############################################################
-# Directory configuration file
-# ##############################################################
-
-
-
-
-# ##############################################################
-# Directory server configuration
-
-
-# URL and type of uplink server. Forward all requests that we cannot satisfy here to uplink
-# - URL of uplink directory server
-# - Type of uplink server. Currently supported is BASYS (BaSys registry API) or DNS (DNS server processing legalBody tag) 
-cfg.uplink       = 
-cfg.uplink.type  = DNS
-
-
-# Downlink servers, forward matching URI patterns to downlink servers
-# - Match all subunits that end with "is.iese", including "is.iese"
-cfg.downlink.is.pattern   = is.iese
-cfg.downlink.is.directory = http://wherever1
-
-# - Match all subunits that end with "pm.iese", including "pm.iese"
-cfg.downlink.pm.pattern   = pm.iese
-cfg.downlink.pm.directory = http://wherever2
-
-# - Match all subunits that end with ".es.iese", but not "es.iese"
-cfg.downlink.es.pattern   = .es.iese
-cfg.downlink.es.directory = http://wherever3
-
-
-
-
-# ##############################################################
-# SQL database configuration
-
-dbuser             = postgres
-dbpass             = admin
-#dburl              = //localhost/basyx-directory?
-# use container link "postgres" instead of localhost when running with docker-compose
-dburl              = //postgres:5432/basyx-directory? 
-
-sqlDriver          = org.postgresql.Driver
-sqlPrefix          = jdbc:postgresql:
diff --git a/examples/basys.registry/WebContent/WEB-INF/config/postgres/init.sql b/examples/basys.registry/WebContent/WEB-INF/config/postgres/init.sql
deleted file mode 100644
index b2930bc..0000000
--- a/examples/basys.registry/WebContent/WEB-INF/config/postgres/init.sql
+++ /dev/null
@@ -1,9 +0,0 @@
-\c basyx-directory
-CREATE SCHEMA directory;
-CREATE TABLE directory.directory ( "ElementRef" varchar(999999), "ElementID" varchar(999999) primary key );
-INSERT INTO directory.directory ( "ElementID", "ElementRef" ) VALUES ( 'urn:de.FHG:es.iese:aas:0.98:5:lab/microscope#A-19', 'content.aas1' );
-INSERT INTO directory.directory ( "ElementID", "ElementRef" ) VALUES ( 'urn:de.FHG:es.iese:aas:0.98:5:lab/microscope#A-18', 'content.aas2' );
-INSERT INTO directory.directory ( "ElementID", "ElementRef" ) VALUES ( 'urn:de.FHG:es.iese:aas:0.98:5:lab/microscope#A-17', 'content.aas3' );
-INSERT INTO directory.directory ( "ElementID", "ElementRef" ) VALUES ( 'urn:de.FHG:es.iese:aas:0.98:5:lab/microscope#A-16', 'content.aas4' );
-INSERT INTO directory.directory ( "ElementID", "ElementRef" ) VALUES ( 'urn:de.FHG:es.iese:aas:0.98:5:lab/microscope#A-15', 'content.aas5' );
-
diff --git a/examples/basys.registry/WebContent/WEB-INF/web.xml b/examples/basys.registry/WebContent/WEB-INF/web.xml
deleted file mode 100644
index f42e738..0000000
--- a/examples/basys.registry/WebContent/WEB-INF/web.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
-  <display-name>registry</display-name>
-  <welcome-file-list>
-    <welcome-file>index.html</welcome-file>
-    <welcome-file>index.htm</welcome-file>
-    <welcome-file>index.jsp</welcome-file>
-    <welcome-file>default.html</welcome-file>
-    <welcome-file>default.htm</welcome-file>
-    <welcome-file>default.jsp</welcome-file>
-  </welcome-file-list>
-  <servlet>
-    <description></description>
-    <display-name>SQLDirectoryServlet</display-name>
-    <servlet-name>SQLDirectoryServlet</servlet-name>
-    <servlet-class>main.java.registry.CustomSQLDirectoryServlet</servlet-class>
-  </servlet>
-  <servlet-mapping>
-    <servlet-name>SQLDirectoryServlet</servlet-name>
-    <url-pattern>/*</url-pattern>
-  </servlet-mapping>
-</web-app>
\ No newline at end of file
diff --git a/examples/basys.registry/docker-compose.yml b/examples/basys.registry/docker-compose.yml
deleted file mode 100644
index e547619..0000000
--- a/examples/basys.registry/docker-compose.yml
+++ /dev/null
@@ -1,31 +0,0 @@
-version: '3'
-services:
-      
-  registry:
-    image: basys:0.0.3-SNAPSHOT
-    container_name: aasRegistry
-    ports:
-      - 8081:8080
-    depends_on:
-      - postgres
-    volumes:
-      -  .\WebContent\WEB-INF\config\directory\sqldirectory\directory.properties:/basys/directory.properties
-    links:
-      - postgres
-
-  postgres:
-    image: postgres:9.4
-    container_name: postgres
-    environment:
-      - POSTGRES_USER:'postgres'
-      - POSTGRES_PASSWORD:'admin'
-      - POSTGRES_DB=basyx-directory
-    volumes:
-      - ./WebContent/WEB-INF/config/postgres/init.sql:/docker-entrypoint-initdb.d/init.sql
-    ports:
-      - 5433:5432
-    expose:
-      - 5432
-            
-
-      
\ No newline at end of file
diff --git a/examples/basys.registry/how-to-use-this-project.txt b/examples/basys.registry/how-to-use-this-project.txt
deleted file mode 100644
index 7bddff0..0000000
--- a/examples/basys.registry/how-to-use-this-project.txt
+++ /dev/null
@@ -1,41 +0,0 @@
-@author pschorn, 07.08.2019
-
-This project demonstrates how to use Maven to create "parameterized" Docker images and how to start multiple containers interacting with each other in a docker-compose file.
-The most important files you need to look at are:
-- /Dockerfile
-- /pom.xml
-- /docker-compose.yml
-- /WebContent/WEB-INF/config/directory/sqldirectory/directory.properties
-- /WebContent/WEB-INF/config/directory/postgres/init.sql
-- /WebContent/WEB-INF/web.xml
-
-
-In detail, the project will create a self-sustained, containerized version of the Registry with SQL backend. For this, we need a PostgreSQL 
-server and the SQLDirectoryServlet from the basys.components project, that processes and forwards requests to the SQL server.
-
-The build process is automated with Maven, which will do the following steps:
- 1) After running unit tests a .war file will be created 
- 2) Maven will build a docker image based on the provided Dockerfile. It will make sure that the .war file of our app is deployed to a TomCat image.
- 3) Before running the integration tests, Maven will run the docker-compose script. "docker-compose up" is used to start a number of containers in a virtual network that can interact with each other.
- 	- Due to the "depends_on" command, docker-compose will start the postgres service first
- 	- The postgres image takes environment variables such as user, password and a database to be created, and we mount a file called init.sql to the postgres' /docker-entrypoint-initdb.d folder that contains the insert 
- 	  statements required to setup the test suite. On startup, postgres will execute all sql scripts that it can find in this directory.
- 	- The "ports" - 5433:5432 command defines that the container should be available for the outside world at port 5433 and forward requests to port 5432 of the application running inside it.
- 	- The "expose" - 5432 commands defines that the other containers started by docker-compose can find the postgres server at this port. Further, together with the "links" - postgres command in
- 	  the registry service definition, the registry can reach the postgres database at //postgres:5432/basyx-directory.
- 	- When the postgres service is started, the registry service will start in the same manner, mounting a directory.properties file to the tomcat container. A Java Implementation trying to access the file should 
- 	  do so by creating an InputStream witht the absolute path to this file.
-4) Now, Maven will start the integration tests, running against the outside-world address of the registry service at http://localhost:8081/registry/
-5) After the tests complete, Maven will tear down the containers with the docker-compose down command.
-
-
-
-# What you should do before production use?
-- make the sql data persistent by mounting a volume to postgres as described here https://stackoverflow.com/questions/41637505/how-to-persist-data-in-a-dockerized-postgres-database-using-volumes
-and be ready to enter the stormy seas of distributed systems.
- 	  
- 
-
-
-
-
diff --git a/examples/basys.registry/pom.xml b/examples/basys.registry/pom.xml
deleted file mode 100644
index 37bb38a..0000000
--- a/examples/basys.registry/pom.xml
+++ /dev/null
@@ -1,145 +0,0 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <groupId>org.eclipse.basys</groupId>
-  <artifactId>registry</artifactId>
-  <version>0.0.3-SNAPSHOT</version>
-  <packaging>war</packaging>
-  <build>
-    <plugins>
-      <plugin>
-        <artifactId>maven-compiler-plugin</artifactId>
-        <version>3.7.0</version>
-        <configuration>
-          <source>1.8</source>
-          <target>1.8</target>
-        </configuration>
-      </plugin>
-      <plugin>
-        <artifactId>maven-war-plugin</artifactId>
-        <version>3.0.0</version>
-        <configuration>
-          <warSourceDirectory>WebContent</warSourceDirectory>
-        </configuration>
-      </plugin>
-       <!-- Build docker image  -->
-		<plugin>
-	       	<groupId>com.spotify</groupId>
-	            <artifactId>dockerfile-maven-plugin</artifactId>
-	            <version>1.4.3</version>
-	            <executions>
-	                <execution>
-	                    <id>default</id>
-	                    <goals>
-	                        <goal>build</goal>
-	                    </goals>
-	                </execution>
-	            </executions>
-	            <configuration>
-	             <imageName>registry</imageName>
-	             <repository>basys</repository>
-	             <tag>${project.version}</tag>
-	            </configuration>
-	        </plugin>
-          <!-- exclude sql tests from unit tests -->
-          <plugin>
-	         <groupId>org.apache.maven.plugins</groupId>
-	         <artifactId>maven-surefire-plugin</artifactId>
-	         <version>2.12.1</version>
-	         <configuration>
-	    		<excludes>
-	      			<exclude>**/*SQL*</exclude>
-	    		</excludes>
-	  		 </configuration>
-	     </plugin>
-         <!-- Create Integration Test environment -->
-         <plugin>
-             <groupId>com.dkanejs.maven.plugins</groupId>
-             <artifactId>docker-compose-maven-plugin</artifactId>
-             <version>1.0.1</version>
-             <configuration>
-                 <composeFile>${project.basedir}/docker-compose.yml</composeFile>
-                 <detachedMode>true</detachedMode>
-             </configuration>
-             <executions>
-                 <execution>
-                     <id>docker-compose-up</id>
-                     <phase>pre-integration-test</phase>
-                     <goals>
-                         <goal>up</goal>
-                     </goals>
-                 </execution>
-                 <execution>
-                     <id>docker-compose-down</id>
-                     <phase>post-integration-test</phase>
-                     <goals>
-                         <goal>down</goal>
-                     </goals>
-                 </execution>
-             </executions>
-         </plugin>
-        
-         <!-- run integration tests -->
-         <plugin>    
-             <groupId>org.apache.maven.plugins</groupId>
-             <artifactId>maven-failsafe-plugin</artifactId>
-             <version>2.20.1</version>
-             <dependencies>
-                 <dependency>
-                     <groupId>org.apache.maven.surefire</groupId>
-                     <artifactId>surefire-junit47</artifactId>
-                     <version>2.20.1</version>
-                 </dependency>
-             </dependencies>
-             <configuration>
-			    <includes>
-			      <include>TestDirectorySQLProviderExtension.java</include>
-			    </includes>
-			  </configuration>
-             <executions>
-                 <execution>
-                     <id>integration-test</id>
-                     <phase>integration-test</phase>
-                     <goals>
-                         <goal>integration-test</goal>
-                     </goals>
-                 </execution>
-                 <execution>
-                     <id>verify</id>
-                     <phase>verify</phase>
-                     <goals>
-                         <goal>verify</goal>
-                     </goals>
-                 </execution>
-             </executions>
-         </plugin>
-         
-    </plugins>
-  </build>
-  <dependencies>
-    <dependency>
-    	<groupId>junit</groupId>
-    	<artifactId>junit</artifactId>
-   		<version>4.12</version>
-	</dependency>
-    <dependency>
-		<groupId>org.eclipse.basyx</groupId>
-		<artifactId>basyx.components</artifactId>
-		<version>0.0.1-SNAPSHOT</version>
-	</dependency>
-	<dependency>
-		<groupId>org.eclipse.basyx</groupId>
-		<artifactId>basyx.components</artifactId>
-		<version>0.0.1-SNAPSHOT</version>
-	</dependency>
-	<!-- Adds additional classes of the BaSys Components for tests -->
-	<dependency>
-		<groupId>org.eclipse.basyx</groupId>
-		<artifactId>basyx.components</artifactId>
-		<version>0.0.1-SNAPSHOT</version>
-		<classifier>tests</classifier>
-		<scope>test</scope>
-	</dependency>
-  </dependencies>
-  <name>BaSys Registry Server</name>
-  <description>...</description>
-</project>
\ No newline at end of file
diff --git a/examples/basys.registry/src/main/java/registry/CustomSQLDirectoryServlet.java b/examples/basys.registry/src/main/java/registry/CustomSQLDirectoryServlet.java
deleted file mode 100644
index 9ec4623..0000000
--- a/examples/basys.registry/src/main/java/registry/CustomSQLDirectoryServlet.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package registry;
-
-
-import org.eclipse.basyx.components.servlets.SQLDirectoryServlet;
-
-
-/**
- * SQL database based directory provider
- * 
- * This directory provider provides a static directory. It therefore only
- * supports get() operations. Modification of the directory via
- * PUT/POST/PATCH/DELETE operations is not supported.
- * 
- * @author kuhn, pschorn
- *
- */
-public class CustomSQLDirectoryServlet extends SQLDirectoryServlet {
-
-	
-	private static final long serialVersionUID = 1L;
-
-	/**
-	 * Path to the directory.properties file, that contains config data for the SQL
-	 * connection
-	 */
-	private static String configFilePath = "/basys/directory.properties";
-
-
-	/**
-	 * Provide HTTP interface with JSONProvider to handle serialization and
-	 * SQLDirectoryProvider as backend
-	 */
-	public CustomSQLDirectoryServlet() {
-		super(configFilePath);
-
-	}
-
-	
-}
-
diff --git a/examples/basys.registry/src/test/java/TestDirectorySQLProviderExtension.java b/examples/basys.registry/src/test/java/TestDirectorySQLProviderExtension.java
deleted file mode 100644
index 9d3a244..0000000
--- a/examples/basys.registry/src/test/java/TestDirectorySQLProviderExtension.java
+++ /dev/null
@@ -1,27 +0,0 @@
-import org.eclipse.basyx.regression.directory.sql.TestDirectorySQLProvider;
-
-/**
- * Test queries to SQL directory provider. Tomcat server and postgres db is
- * started by docker compose
- * 
- * @author kuhn, ps
- *
- */
-public class TestDirectorySQLProviderExtension extends TestDirectorySQLProvider {
-
-	// Directory web service URL
-	@Override
-	public void setUp() {
-		this.wsURL = "http://localhost:8081/registry";
-
-		try {
-			Thread.sleep(100);
-		} catch (InterruptedException e) {
-			e.printStackTrace();
-		}
-	}
-
-	public TestDirectorySQLProviderExtension() {
-		super();
-	}
-}
diff --git a/examples/basyx.aasWrapper/.gitignore b/examples/basyx.aasWrapper/.gitignore
new file mode 100644
index 0000000..02eeb17
--- /dev/null
+++ b/examples/basyx.aasWrapper/.gitignore
@@ -0,0 +1,69 @@
+.classpath
+.project
+
+regressiontest/
+target/
+pom.xml.tag
+pom.xml.releaseBackup
+pom.xml.versionsBackup
+pom.xml.next
+release.properties
+dependency-reduced-pom.xml
+buildNumber.properties
+.mvn/timing.properties
+.mvn/wrapper/maven-wrapper.jar
+.metadata
+bin/
+tmp/
+*.tmp
+*.bak
+*.swp
+*~.nib
+local.properties
+.settings/
+.loadpath
+.recommenders
+
+# External tool builders
+.externalToolBuilders/
+
+# Locally stored "Eclipse launch configurations"
+*.launch
+
+# PyDev specific (Python IDE for Eclipse)
+*.pydevproject
+
+# CDT-specific (C/C++ Development Tooling)
+.cproject
+
+# CDT- autotools
+.autotools
+
+# Java annotation processor (APT)
+.factorypath
+
+# PDT-specific (PHP Development Tools)
+.buildpath
+
+# sbteclipse plugin
+.target
+
+# Tern plugin
+.tern-project
+
+# TeXlipse plugin
+.texlipse
+
+# STS (Spring Tool Suite)
+.springBeans
+
+# Code Recommenders
+.recommenders/
+
+# Annotation Processing
+.apt_generated/
+
+# Scala IDE specific (Scala & Java development for Eclipse)
+.cache-main
+.scala_dependencies
+.worksheet
\ No newline at end of file
diff --git a/examples/basyx.aasWrapper/Dockerfile b/examples/basyx.aasWrapper/Dockerfile
new file mode 100644
index 0000000..5c98c98
--- /dev/null
+++ b/examples/basyx.aasWrapper/Dockerfile
@@ -0,0 +1,23 @@
+# Add java runtime environment for execution
+FROM java:8-jdk-alpine 
+
+# Copy built jar to image using the jar name specified in the pom.xml (JAR_FILE)
+ARG JAR_FILE
+COPY target/${JAR_FILE} /usr/share/basyxExecutable.jar
+COPY target/lib /usr/share/lib
+COPY src/main/resources/context.properties /usr/share/config/context.properties
+COPY src/main/resources/wrapper.properties /usr/share/config/wrapper.properties
+
+# Expose the appropriate port. In case of Tomcat, this is 8080.
+ARG PORT
+EXPOSE ${PORT}
+
+# Set the path for the context configuration file
+ARG CONTEXT_CONFIG_KEY
+ENV ${CONTEXT_CONFIG_KEY} "/usr/share/config/context.properties"
+
+# Set the path for the context configuration file
+ENV BASYX_WRAPPER "/usr/share/config/wrapper.properties"
+ 
+# Start the jar
+CMD java -jar "/usr/share/basyxExecutable.jar"
\ No newline at end of file
diff --git a/examples/basyx.aasWrapper/build.bat b/examples/basyx.aasWrapper/build.bat
new file mode 100644
index 0000000..0977f37
--- /dev/null
+++ b/examples/basyx.aasWrapper/build.bat
@@ -0,0 +1 @@
+.././mvnw clean install -U -Pdocker
\ No newline at end of file
diff --git a/examples/basyx.aasWrapper/build.sh b/examples/basyx.aasWrapper/build.sh
new file mode 100644
index 0000000..d223f82
--- /dev/null
+++ b/examples/basyx.aasWrapper/build.sh
@@ -0,0 +1,2 @@
+#!/usr/bin/env sh
+.././mvnw clean install -U -Pdocker -DskipTests
\ No newline at end of file
diff --git a/examples/basyx.aasWrapper/docker-compose.yml b/examples/basyx.aasWrapper/docker-compose.yml
new file mode 100644
index 0000000..fe990ac
--- /dev/null
+++ b/examples/basyx.aasWrapper/docker-compose.yml
@@ -0,0 +1,23 @@
+version: '3'
+services:
+
+  registry:
+    image: eclipsebasyx/aas-registry:1.0.1
+    container_name: dashboard-registry
+    ports:
+      - 4000:4000
+
+  dashboard-aas:
+    image: eclipsebasyx/dashboard-aas:0.1.0-SNAPSHOT
+    container_name: dashboard-aas
+    environment:
+      - BaSyxDashboardSubmodel_Min=15
+#      - BaSyxDashboardSubmodel_Max=30
+    ports:
+      - 6400:6400
+
+  aas-wrapper:
+    image: eclipsebasyx/aas-wrapper:0.1.0-SNAPSHOT
+    container_name: aas-wrapper
+    ports:
+      - 6500:6500
\ No newline at end of file
diff --git a/examples/basyx.aasWrapper/pom.xml b/examples/basyx.aasWrapper/pom.xml
new file mode 100644
index 0000000..599b939
--- /dev/null
+++ b/examples/basyx.aasWrapper/pom.xml
@@ -0,0 +1,66 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<parent>
+		<groupId>org.eclipse.basyx</groupId>
+		<artifactId>basyx.components.docker</artifactId>
+		<version>1.0.0</version>
+	</parent>
+	
+	<artifactId>basyx.components.AASWrapper</artifactId>
+	<name>BaSyx AAS Wrapper</name>
+	
+	<properties>
+		<!--  
+			basyx.components.executable is the executable class with the definition of the public void main(String[]).
+			It is needed when building the jar in the maven-jar-plugin (see basyx.components.docker/pom.xml) 
+		-->
+		<basyx.components.executable>org.eclipse.basyx.wrapper.AASWrapperExecutable</basyx.components.executable>
+	</properties>
+	
+	<packaging>jar</packaging>
+	
+	<!-- Define additional plugins that are not included by default -->
+	<!-- Plugin configuration is done in parent project(s) -->
+	<build>
+		<plugins>
+			<!-- Attach sources to jar file -->
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-source-plugin</artifactId>
+			</plugin>
+		</plugins>
+	</build>
+	
+	<profiles>
+		<profile>
+			<!-- 
+				"Docker" profile - do not build & install docker images by default
+				Run "mvn install -Pdocker" in order to include docker  
+			-->
+			<id>docker</id>
+			<build>
+				<plugins>
+					<!-- Read maven properties from file -->
+					<plugin>
+						<groupId>org.codehaus.mojo</groupId>
+						<artifactId>properties-maven-plugin</artifactId>
+					</plugin>
+				
+					<!-- Copy the dependencies necessary to run the jar -->
+					<plugin>
+						<groupId>org.apache.maven.plugins</groupId>
+						<artifactId>maven-dependency-plugin</artifactId>
+					</plugin>
+				
+					<!-- Build the docker image -->
+					<plugin>
+						<groupId>com.spotify</groupId>
+						<artifactId>dockerfile-maven-plugin</artifactId>
+					</plugin>
+				</plugins>
+			</build>
+		</profile>
+	</profiles>
+</project>
\ No newline at end of file
diff --git a/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/AASWrapperExecutable.java b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/AASWrapperExecutable.java
new file mode 100644
index 0000000..36e1bc3
--- /dev/null
+++ b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/AASWrapperExecutable.java
@@ -0,0 +1,209 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.wrapper;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
+import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
+import org.eclipse.basyx.components.configuration.BaSyxConfiguration;
+import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
+import org.eclipse.basyx.vab.protocol.http.server.BaSyxHTTPServer;
+import org.eclipse.basyx.vab.protocol.http.server.BaSyxContext;
+import org.eclipse.basyx.wrapper.provider.GenericHTTPInterface;
+import org.eclipse.basyx.wrapper.provider.GenericWrapperProvider;
+import org.eclipse.basyx.wrapper.provider.IWrapperProvider;
+import org.eclipse.basyx.wrapper.provider.aas.AASWrapperProvider;
+import org.eclipse.basyx.wrapper.provider.grafana.GrafanaProvider;
+import org.eclipse.basyx.wrapper.provider.streamsheets.StreamsheetsProvider;
+import org.eclipse.basyx.wrapper.receiver.IPropertyWrapperService;
+import org.eclipse.basyx.wrapper.receiver.SeparateAASService;
+import org.eclipse.basyx.wrapper.receiver.configuration.AASPropertyConfiguration;
+import org.eclipse.basyx.wrapper.receiver.configuration.PropertyConfiguration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Runs the AAS wrapper for the given configuration. The configuration is loaded
+ * from the wrapper.properties by default, but can also be given by an external file.
+ * For this, the path has to be specified in the BASYX_WRAPPER java property or system
+ * environment variable.
+ * 
+ * @author espen
+ *
+ */
+public class AASWrapperExecutable {
+	private static final Logger logger = LoggerFactory.getLogger(AASWrapperExecutable.class);
+	public static final int PORT = 6500;
+	public static final String HOST = "aas-wrapper";
+
+	private static String registryAddress;
+	private static Map<String, PropertyConfiguration> propertyConfigs;
+	private static Map<String, String> activeProviders = new HashMap<>();
+	private static Map<String, String> providerPaths = new HashMap<>();
+
+	public static void main(String[] args) throws Exception {
+		logger.info("Wrapper started, waiting for other components");
+		// Use docker-compose health check for registry and aas instead
+		Thread.sleep(6000);
+
+		logger.info("Loading configuration...");
+		loadConfigs("wrapper.properties");
+
+		logger.info("Creating proxy for " + propertyConfigs.size() + " properties...");
+		IAASRegistry registry = new AASRegistryProxy(registryAddress);
+		IPropertyWrapperService connector = new SeparateAASService(registry, propertyConfigs.values());
+
+		logger.info("Creating " + activeProviders.size() + " providers...");
+		List<IWrapperProvider> providers = createProxyProviders();
+		providers.forEach(p -> p.initialize(connector, registry, propertyConfigs.values()));
+
+		if (!providers.isEmpty()) {
+			logger.info("Starting property proxy service...");
+			connector.start();
+			logger.info("Starting proxy providers...");
+			createServlet(providers);
+		} else {
+			logger.info("No providers have been created!");
+		}
+
+		logger.info("Finished");
+	}
+
+	private static List<IWrapperProvider> createProxyProviders() {
+		List<IWrapperProvider> providers = new ArrayList<>();
+		for (Entry<String, String> entry : activeProviders.entrySet()) {
+			String providerId = entry.getKey();
+			String providerType = entry.getValue();
+			IWrapperProvider newProvider;
+			switch (providerType) {
+				case (AASWrapperProvider.TYPE):
+					newProvider = new AASWrapperProvider(HOST, PORT);
+					break;
+				case (GrafanaProvider.TYPE):
+					newProvider = new GrafanaProvider();
+					break;
+				case (StreamsheetsProvider.TYPE):
+					newProvider = new StreamsheetsProvider();
+					break;
+				default:
+					newProvider = new GenericWrapperProvider();
+			}
+			String newPath = providerPaths.get(providerId);
+			if (newPath != null) {
+				newProvider.setProviderPath(newPath);
+			}
+			providers.add(newProvider);
+		}
+		return providers;
+	}
+
+	private static void loadConfigs(String resourceFileName) {
+		// Load resource file
+		logger.info("Loading proxy property file " + resourceFileName);
+		Map<String, String> configMap = new HashMap<>();
+		BaSyxConfiguration config = new BaSyxConfiguration(configMap);
+		config.loadFileOrDefaultResource("BASYX_WRAPPER", "wrapper.properties");
+
+		loadRegistryConfig(config);
+		propertyConfigs = loadPropertyConfigs(configMap);
+		loadProviderConfigs(configMap);
+	}
+
+	private static void loadRegistryConfig(BaSyxConfiguration config) {
+		registryAddress = config.getProperty("registry.endpoint");
+		logger.info("Registry address: " + registryAddress);
+	}
+
+	private static Map<String, PropertyConfiguration> loadPropertyConfigs(Map<String, String> configMap) {
+		Map<String, PropertyConfiguration> configs = new HashMap<>();
+		for (Entry<String, String> entry : configMap.entrySet()) {
+			String key = entry.getKey();
+			String[] propKeys = key.split("\\.");
+			if (propKeys.length != 3 || !propKeys[0].equals(PropertyConfiguration.INDEX)) {
+				continue;
+			}
+
+			String propId = propKeys[1];
+			String parameter = propKeys[2];
+			String value = entry.getValue();
+			if (!configs.containsKey(propId)) {
+				logger.info("Creating property " + propId);
+				PropertyConfiguration propConfig = new PropertyConfiguration();
+				propConfig.setId(propId);
+				configs.put(propId, propConfig);
+			}
+			setPropertyParameter(configs, propId, parameter, value);
+		}
+		return configs;
+	}
+
+	private static void loadProviderConfigs(Map<String, String> configMap) {
+		for (Entry<String, String> entry : configMap.entrySet()) {
+			String key = entry.getKey();
+			String[] propKeys = key.split("\\.");
+			if (propKeys.length != 3 || !propKeys[0].equals(GenericWrapperProvider.INDEX)) {
+				continue;
+			}
+
+			String providerId = propKeys[1];
+			String parameter = propKeys[2];
+			String value = entry.getValue();
+
+			switch (parameter) {
+				case ("type"):
+					activeProviders.put(providerId, value);
+					logger.info("Setting provider '" + providerId + "': type=" + value);
+					break;
+				case ("path"):
+					providerPaths.put(providerId, value);
+					logger.info("Setting provider '" + providerId + "': path=" + value);
+					break;
+				default:
+					logger.info("Invalid config for provider '" + providerId + "': " + parameter + "=" + value);
+			}
+
+		}
+	}
+
+	private static void setPropertyParameter(Map<String, PropertyConfiguration> configs, String propId,
+			String parameter, String value) {
+		logger.info("Setting property '" + propId + "': " + parameter + "=" + value);
+		PropertyConfiguration prop = configs.get(propId);
+		prop.put(parameter, value);
+		if (parameter.equals(PropertyConfiguration.TYPE)) {
+			// Possibility to add more property types
+			switch (value) {
+				case (AASPropertyConfiguration.TYPE):
+					configs.put(propId, new AASPropertyConfiguration(prop));
+					break;
+				default:
+					logger.error("Unknown property type: " + value);
+			}
+		}
+	}
+
+	private static void createServlet(List<IWrapperProvider> providers) {
+		BaSyxContextConfiguration contextConfig = new BaSyxContextConfiguration();
+		contextConfig.loadFromDefaultSource();
+		BaSyxContext context = contextConfig.createBaSyxContext();
+		for (IWrapperProvider provider : providers) {
+			context.addServletMapping(provider.getProviderPath() + "/*",
+					new GenericHTTPInterface(provider));
+		}
+        BaSyxHTTPServer server = new BaSyxHTTPServer(context);
+		server.start();
+	}
+}
+
diff --git a/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/exception/WrapperRequestException.java b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/exception/WrapperRequestException.java
new file mode 100644
index 0000000..87c90d0
--- /dev/null
+++ b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/exception/WrapperRequestException.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.wrapper.exception;
+
+/**
+ * Exception that is thrown when the wrapper cannot request a value from its datasource
+ * 
+ * @author espen
+ *
+ */
+public class WrapperRequestException extends RuntimeException {
+    private static final long serialVersionUID = 1L;
+
+    public WrapperRequestException(String message) {
+        super(message);
+    }
+
+    public WrapperRequestException(String message, Throwable error) {
+        super(message, error);
+    }
+
+}
diff --git a/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/provider/GenericHTTPInterface.java b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/provider/GenericHTTPInterface.java
new file mode 100644
index 0000000..0d8f4eb
--- /dev/null
+++ b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/provider/GenericHTTPInterface.java
@@ -0,0 +1,252 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.wrapper.provider;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.StringJoiner;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.basyx.vab.exception.provider.MalformedRequestException;
+import org.eclipse.basyx.vab.exception.provider.ProviderException;
+import org.eclipse.basyx.vab.modelprovider.VABPathTools;
+import org.eclipse.basyx.vab.protocol.http.server.BasysHTTPServlet;
+import org.eclipse.basyx.vab.protocol.http.server.ExceptionToHTTPCodeMapper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.io.ByteSource;
+
+/**
+ * Implements a generic HTTP interface based on a JSONProvider that implements
+ * GET, PUT, POST, PATCH and DELETE and supports returning objects for each of the
+ * primitive. For PUT, POST and PATCH, it also supports passing objects.
+ * 
+ * @author espen
+ *
+ */
+public class GenericHTTPInterface extends BasysHTTPServlet {
+	private static Logger logger = LoggerFactory.getLogger(GenericHTTPInterface.class);
+	
+	private static final String CHARSET = "UTF-8";
+	private static final String MIMETYPE = "application/json";
+
+	/**
+	 * Version information to identify the version of serialized instances
+	 */
+	private static final long serialVersionUID = 1L;
+
+	private final JSONProvider provider;
+
+	/**
+	 * Constructor
+	 */
+	public GenericHTTPInterface(IWrapperProvider backend) {
+		this.provider = new JSONProvider(backend);
+	}
+
+	/**
+	 * Implement "Get" operation
+	 * 
+	 * Process HTTP get request - get sub model property value
+	 */
+	@Override
+	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+		try {
+			String path = extractPath(req);
+			prepareResponse(resp);
+			provider.processGet(path, resp.getOutputStream());
+		} catch (IOException e) {
+			logger.warn("Exception in HTTP-GET", e);
+		} catch (ProviderException e) {
+			int httpCode = ExceptionToHTTPCodeMapper.mapFromException(e);
+			resp.setStatus(httpCode);
+			logger.debug("Exception in GET request - response-code: " + httpCode, e);
+		}
+	}
+	
+	/**
+	 * Implement "Set" operation
+	 */
+	@Override
+	protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+		try {
+			String path = extractPath(req);
+			String serValue = extractSerializedValue(req);
+			prepareResponse(resp);
+			provider.processPut(path, serValue, resp.getOutputStream());
+		} catch (IOException e) {
+			logger.warn("Exception in HTTP-PUT", e);
+		} catch (ProviderException e) {
+			int httpCode = ExceptionToHTTPCodeMapper.mapFromException(e);
+			resp.setStatus(httpCode);
+			logger.debug("Exception in PUT request - response-code: " + httpCode, e);
+		}
+	}
+
+	
+	/**
+	 * <pre>
+	 * Handle HTTP POST operation. Creates a new Property, Operation, Event,
+	 * Submodel or AAS or invokes an operation.
+	 */
+	@Override
+	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+		try {
+			String path = extractPath(req);
+			String serValue = extractSerializedValue(req);
+			prepareResponse(resp);
+			provider.processPost(path, serValue, resp.getOutputStream());
+		} catch (IOException e) {
+			logger.warn("Exception in HTTP-POST", e);
+		} catch (ProviderException e) {
+			int httpCode = ExceptionToHTTPCodeMapper.mapFromException(e);
+			resp.setStatus(httpCode);
+			logger.debug("Exception in POST request - response-code: " + httpCode, e);
+		}
+	}
+
+	
+	/**
+	 * Handle a HTTP PATCH operation. Updates a map or collection
+	 * 
+	 */
+	@Override
+	protected void doPatch(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+		try {
+			String path = extractPath(req);
+			String serValue = extractSerializedValue(req);
+			prepareResponse(resp);
+			provider.processPatch(path, serValue, resp.getOutputStream());
+		} catch (IOException e) {
+			logger.warn("Exception in HTTP-PATCH", e);
+		} catch (ProviderException e) {
+			int httpCode = ExceptionToHTTPCodeMapper.mapFromException(e);
+			resp.setStatus(httpCode);
+			logger.debug("Exception in PATCH request - response-code: " + httpCode, e);
+		}
+	}
+
+	
+	/**
+	 * Implement "Delete" operation. Deletes any resource under the given path.
+	 */
+	@Override
+	protected void doDelete(HttpServletRequest req, HttpServletResponse resp) {
+		try {
+			String path = extractPath(req);
+			prepareResponse(resp);
+			provider.processDelete(path, resp.getOutputStream());
+		} catch (IOException e) {
+			logger.warn("Exception in HTTP-DELETE", e);
+		} catch (ProviderException e) {
+			int httpCode = ExceptionToHTTPCodeMapper.mapFromException(e);
+			resp.setStatus(httpCode);
+			logger.debug("Exception in DELETE request - response-code: " + httpCode, e);
+		}
+	}
+
+	
+	private String extractPath(HttpServletRequest req) {
+		// Extract path
+		String uri = req.getRequestURI();
+
+		// Normalizes URI
+		String nUri = "/" + VABPathTools.stripSlashes(uri);
+		String contextPath = req.getContextPath();
+		if (nUri.startsWith(contextPath) && nUri.length() > getEnvironmentPathSize(req) - 1) {
+			String path = nUri.substring(getEnvironmentPathSize(req));
+			String extractedParameters = extractParameters(req);
+
+			path = VABPathTools.stripSlashes(path);
+
+			if (extractedParameters.isEmpty()) {
+				path += "/";
+			} else {
+				path += extractedParameters;
+			}
+			return path;
+		}
+		throw new MalformedRequestException("The passed path " + uri + " is not a possbile path for this server.");
+	}
+
+	/**
+	 * Extracts request parameters from the request
+	 * 
+	 * @param req
+	 * @return
+	 */
+	private String extractParameters(HttpServletRequest req) {
+		Enumeration<String> parameterNames = req.getParameterNames();
+		
+		// Collect list of parameters
+		List<String> parameters = new ArrayList<>();
+		while (parameterNames.hasMoreElements()) {
+
+			StringBuilder ret = new StringBuilder();
+			String paramName = parameterNames.nextElement();
+			ret.append(paramName);
+			ret.append("=");
+
+			String[] paramValues = req.getParameterValues(paramName);
+			for (int i = 0; i < paramValues.length; i++) {
+				ret.append(paramValues[i]);
+			}
+			parameters.add(ret.toString());
+
+		}
+
+		// If no parameter is existing, return an empty string. Else join the parameters
+		// and return them prefixed with a ?
+		if (parameters.isEmpty()) {
+			return "";
+		} else {
+			StringJoiner joiner = new StringJoiner("&");
+			parameters.stream().forEach(joiner::add);
+			return "?" + joiner.toString();
+		}
+	}
+
+	private int getEnvironmentPathSize(HttpServletRequest req) {
+		return req.getContextPath().length() + req.getServletPath().length();
+	}
+
+
+	/**
+	 * Read serialized value 
+	 * @param req
+	 * @return
+	 * @throws IOException
+	 */
+	private String extractSerializedValue(HttpServletRequest req) throws IOException {
+		// https://www.baeldung.com/convert-input-stream-to-string#guava
+		ByteSource byteSource = new ByteSource() {
+	        @Override
+	        public InputStream openStream() throws IOException {
+	            return req.getInputStream();
+	        }
+	    };
+	 
+		return byteSource.asCharSource(StandardCharsets.UTF_8).read();
+	}
+
+	private void prepareResponse(HttpServletResponse resp) {
+		resp.setContentType(MIMETYPE);
+		resp.setCharacterEncoding(CHARSET);
+		resp.setStatus(200);
+	}
+}
diff --git a/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/provider/GenericWrapperProvider.java b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/provider/GenericWrapperProvider.java
new file mode 100644
index 0000000..3e173d0
--- /dev/null
+++ b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/provider/GenericWrapperProvider.java
@@ -0,0 +1,97 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.wrapper.provider;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
+import org.eclipse.basyx.vab.exception.provider.MalformedRequestException;
+import org.eclipse.basyx.vab.modelprovider.VABPathTools;
+import org.eclipse.basyx.wrapper.receiver.IPropertyWrapperService;
+import org.eclipse.basyx.wrapper.receiver.configuration.PropertyConfiguration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Wraps any connector API with a ModelProvider
+ * 
+ * @author espen
+ *
+ */
+public class GenericWrapperProvider implements IWrapperProvider {
+	public static final String INDEX = "providers";
+	private static final Logger logger = LoggerFactory.getLogger(GenericWrapperProvider.class);
+
+	protected IPropertyWrapperService proxyService;
+	protected String providerPath = "provider";
+	protected Set<String> passiveProperties = new HashSet<>();
+
+	@Override
+	public void initialize(IPropertyWrapperService wrapperService, IAASRegistry registry,
+			Collection<PropertyConfiguration> configs) {
+		logger.info(
+				"Initializing provider '" + this.getClass().getSimpleName() + "' on path " + this.getProviderPath());
+		this.proxyService = wrapperService;
+		for (PropertyConfiguration config : configs) {
+			if (!config.getActive()) {
+				passiveProperties.add(config.getId());
+			}
+		}
+	}
+
+	@Override
+	public Object get(String path) {
+		path = preparePath(path);
+		if ( passiveProperties.contains(path) ) {
+			proxyService.generatePassiveValue(path);
+		}
+		return proxyService.getPropertyValue(path);
+	}
+
+	@Override
+	public Object post(String path, Object newValue) {
+		path = preparePath(path);
+		proxyService.setPropertyValue(path, newValue);
+		return newValue;
+	}
+
+	protected String preparePath(String path) {
+		VABPathTools.checkPathForNull(path);
+		path = VABPathTools.stripSlashes(path);
+		return path;
+	}
+
+	@Override
+	public String getProviderPath() {
+		return providerPath;
+	}
+
+	@Override
+	public void setProviderPath(String path) {
+		this.providerPath = path;
+	}
+
+	@Override
+	public Object delete(String path) {
+		throw new MalformedRequestException("Deleting elements is not supported");
+	}
+
+	@Override
+	public Object put(String path, Object data) {
+		throw new MalformedRequestException("Setting elements is not supported");
+	}
+
+	@Override
+	public Object patch(String path, Object data) {
+		throw new MalformedRequestException("Patching elements is not supported");
+	}
+}
diff --git a/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/provider/HTTPModelProvider.java b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/provider/HTTPModelProvider.java
new file mode 100644
index 0000000..a50d307
--- /dev/null
+++ b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/provider/HTTPModelProvider.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.wrapper.provider;
+
+/**
+ * A simple, generic HTTP-REST model provider
+ * 
+ * @author espen
+ *
+ */
+public interface HTTPModelProvider {
+	public Object get(String path);
+
+	public Object delete(String path);
+
+	public Object put(String path, Object data);
+
+	public Object post(String path, Object data);
+
+	public Object patch(String path, Object data);
+}
diff --git a/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/provider/IWrapperProvider.java b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/provider/IWrapperProvider.java
new file mode 100644
index 0000000..6d4eaa9
--- /dev/null
+++ b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/provider/IWrapperProvider.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.wrapper.provider;
+
+import java.util.Collection;
+
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
+import org.eclipse.basyx.wrapper.receiver.IPropertyWrapperService;
+import org.eclipse.basyx.wrapper.receiver.configuration.PropertyConfiguration;
+
+/**
+ * Interface for a generic connector that makes use of the HTTPModelProvider interface
+ * 
+ * @author espen
+ *
+ */
+public interface IWrapperProvider extends HTTPModelProvider {
+
+	/**
+	 * Returns the path for this provider
+	 * 
+	 * @return
+	 */
+	public String getProviderPath();
+
+	/**
+	 * Sets the path for this provider
+	 * 
+	 * @param path
+	 */
+	public void setProviderPath(String path);
+
+	/**
+	 * Initialize the provider
+	 * 
+	 * @param proxyService
+	 * @param registry
+	 */
+	public void initialize(IPropertyWrapperService proxyService, IAASRegistry registry,
+			Collection<PropertyConfiguration> configs);
+}
diff --git a/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/provider/JSONProvider.java b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/provider/JSONProvider.java
new file mode 100644
index 0000000..f7b4268
--- /dev/null
+++ b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/provider/JSONProvider.java
@@ -0,0 +1,175 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.wrapper.provider;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.charset.StandardCharsets;
+
+import org.eclipse.basyx.vab.coder.json.metaprotocol.Result;
+import org.eclipse.basyx.vab.coder.json.serialization.DefaultTypeFactory;
+import org.eclipse.basyx.vab.coder.json.serialization.GSONTools;
+import org.eclipse.basyx.vab.exception.provider.MalformedRequestException;
+import org.eclipse.basyx.vab.exception.provider.ProviderException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Implementation variant of the JSONProvider for a generic HTTPModelProvider backend
+ * 
+ * @author espen
+ *
+ */
+public class JSONProvider {
+	
+	private static Logger logger = LoggerFactory.getLogger(JSONProvider.class);
+
+	/**
+	 * Reference to serializer / deserializer
+	 */
+	protected GSONTools serializer = null;
+
+	private HTTPModelProvider backend;
+	
+	/**
+	 * Constructor
+	 */
+	public JSONProvider(HTTPModelProvider backend) {
+		this.backend = backend;
+		serializer = new GSONTools(new DefaultTypeFactory());
+	}
+
+	/**
+	 * Marks success as false and delivers exception cause messages 
+	 * @param e
+	 * @return
+	 */
+	private String serialize(Exception e) {
+		// Create Ack
+		Result result = new Result(e);
+		
+		// Serialize the whole thing
+		return serialize(result);
+	}
+	
+	
+	/**
+	 * Serialize IResult (HashMap)
+	 * @param string
+	 * @return
+	 */
+	private String serialize(Result string) {
+		// Serialize the whole thing
+		return serializer.serialize(string);
+	}
+	
+
+	/**
+	 * Send Error
+	 * @param e
+	 * @param path
+	 * @param resp
+	 */
+	private void sendException(OutputStream resp, Exception e) {
+		
+		// Serialize Exception
+		String jsonString = serialize(e);
+		try {
+			resp.write(jsonString.getBytes(StandardCharsets.UTF_8));
+		} catch(IOException innerE) {
+			throw new ProviderException("Failed to send Exception '" + e.getMessage() + "' to client", innerE);
+		}
+		
+		//If the Exception is a ProviderException, just rethrow it
+		if(e instanceof ProviderException) {
+			throw (ProviderException) e;
+		}
+		
+		//If the Exception is not a ProviderException encapsulate it in one and log it
+		logger.error("Unknown Exception in JSONProvider", e);
+		throw new ProviderException(e);
+	}
+
+	
+	/**
+	 * Extracts parameter from JSON and handles de-serialization errors
+	 */
+	private Object extractParameter(String serializedJSONValue) {
+		// Return value
+		Object result = null;
+		try {
+			// Deserialize json body
+			result = serializer.deserialize(serializedJSONValue);
+		} catch (Exception e) {
+			//JSON could not be deserialized
+			throw new MalformedRequestException(e);
+		}
+		
+		return result;
+	}
+	
+
+	public void processGet(String path, OutputStream outputStream) {
+		try {
+			logger.info("GET '" + path + "'");
+			Object value = backend.get(path);
+			String jsonString = serializer.serialize(value);
+			outputStream.write(jsonString.getBytes(StandardCharsets.UTF_8));
+		} catch (Exception e) {
+			sendException(outputStream, e);
+		}
+	}
+
+	public void processDelete(String path, OutputStream outputStream) {
+		try {
+			logger.info("DELETE '" + path + "'");
+			Object value = backend.delete(path);
+			String jsonString = serializer.serialize(value);
+			outputStream.write(jsonString.getBytes(StandardCharsets.UTF_8));
+		} catch (Exception e) {
+			sendException(outputStream, e);
+		}
+	}
+
+	public void processPost(String path, String serializedJSONValue, OutputStream outputStream) {
+		try {
+			Object parameter = extractParameter(serializedJSONValue);
+			Object value = backend.post(path, parameter);
+			String jsonString = serializer.serialize(value);
+			outputStream.write(jsonString.getBytes(StandardCharsets.UTF_8));
+		} catch (Exception e) {
+			sendException(outputStream, e);
+		}
+	}
+
+	public void processPatch(String path, String serializedJSONValue, OutputStream outputStream) {
+		try {
+			logger.info("PATCH " + path + "'");
+			Object parameter = extractParameter(serializedJSONValue);
+			Object value = backend.patch(path, parameter);
+			String jsonString = serializer.serialize(value);
+			outputStream.write(jsonString.getBytes(StandardCharsets.UTF_8));
+		} catch (Exception e) {
+			sendException(outputStream, e);
+		}
+	}
+
+	public void processPut(String path, String serializedJSONValue, OutputStream outputStream) {
+		try {
+			logger.info("PUT " + path + "'");
+			Object parameter = extractParameter(serializedJSONValue);
+			Object value = backend.put(path, parameter);
+			String jsonString = serializer.serialize(value);
+			outputStream.write(jsonString.getBytes(StandardCharsets.UTF_8));
+		} catch (Exception e) {
+			sendException(outputStream, e);
+		}
+	}
+}
diff --git a/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/provider/aas/AASWrapperProvider.java b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/provider/aas/AASWrapperProvider.java
new file mode 100644
index 0000000..917d15f
--- /dev/null
+++ b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/provider/aas/AASWrapperProvider.java
@@ -0,0 +1,147 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.wrapper.provider.aas;
+
+import java.util.Collection;
+
+import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
+import org.eclipse.basyx.aas.metamodel.map.parts.Asset;
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
+import org.eclipse.basyx.aas.restapi.AASModelProvider;
+import org.eclipse.basyx.aas.restapi.MultiSubmodelProvider;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.eclipse.basyx.submodel.restapi.SubmodelProvider;
+import org.eclipse.basyx.vab.exception.provider.MalformedRequestException;
+import org.eclipse.basyx.wrapper.provider.IWrapperProvider;
+import org.eclipse.basyx.wrapper.receiver.IPropertyWrapperService;
+import org.eclipse.basyx.wrapper.receiver.configuration.PropertyConfiguration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * AAS Provider for the wrapper that exposes the GET-Part of the AAS interface
+ * 
+ * @author espen
+ *
+ */
+public class AASWrapperProvider implements IWrapperProvider {
+	private static final Logger logger = LoggerFactory.getLogger(AASWrapperProvider.class);
+	public static final String TYPE = "AAS";
+	
+	private final String host;
+	private final int port;
+
+	private MultiSubmodelProvider provider;
+
+	private String providerPath = "/aas";
+
+	/**
+	 * Standard constructor for the AASWrapperProvider. Needs to know the wrapper endpoint to be able to register the
+	 * created AAS interface
+	 * 
+	 * @param host Host of the wrapper
+	 * @param port Port for the wrapper
+	 */
+	public AASWrapperProvider(String host, int port) {
+		this.host = host;
+		this.port = port;
+	}
+
+	@Override
+	public void initialize(IPropertyWrapperService wrapperService, IAASRegistry registry,
+			Collection<PropertyConfiguration> configs) {
+		logger.info("Initializing provider '" + this.getClass().getSimpleName() + "' on path " + this.getProviderPath());
+
+		// Create the VABMultiSubmodelProvider
+		AssetAdministrationShell aas = new WrapperAssetAdministrationShell();
+		Asset asset = new WrapperAsset();
+		aas.setAsset(asset);
+		Submodel sm = new WrapperSubmodel("Wrapper", new Identifier(IdentifierType.CUSTOM, "WrapperSubmodel"),
+				wrapperService,
+				configs);
+		aas.addSubmodel(sm);
+
+		provider = new MultiSubmodelProvider(new AASModelProvider(aas));
+		provider.addSubmodel(new SubmodelProvider(sm));
+
+		// Register the aas
+		AASDescriptor desc = createDescriptor(aas, sm);
+		registerAAS(registry, desc);
+	}
+
+	private AASDescriptor createDescriptor(AssetAdministrationShell aas, Submodel... submodels) {
+		AASDescriptor descriptor = new AASDescriptor(aas, "http://" + host + ":" + port + "/aas");
+		for (Submodel sm : submodels) {
+			descriptor.addSubmodelDescriptor(
+					new SubmodelDescriptor(sm,
+							"http://" + host + ":" + port + "/aas/submodels/" + sm.getIdShort() + "/"));
+		}
+		return descriptor;
+	}
+
+	private static void registerAAS(IAASRegistry registry, AASDescriptor descriptor) {
+		// Quick & dirty, try to register until registry is up
+		for (int i = 0; i < 10; i++) {
+			try {
+				registry.register(descriptor);
+				break;
+			} catch (Exception e) {
+				try {
+					Thread.sleep(2000);
+				} catch (InterruptedException e1) {
+					logger.warn("Interrupted", e1);
+					Thread.currentThread().interrupt();
+				}
+			}
+		}
+	}
+
+	@Override
+	public String getProviderPath() {
+		return providerPath;
+	}
+
+	@Override
+	public void setProviderPath(String path) {
+		this.providerPath = path;
+	}
+
+	@Override
+	public Object post(String path, Object data) {
+		throw new MalformedRequestException("Creating elements is not supported");
+	}
+
+	/**
+	 * Only expose the get-Part of the HTTP-REST Interface of the AAS
+	 */
+	@Override
+	public Object get(String path) {
+		return provider.getValue(path);
+	}
+
+	@Override
+	public Object delete(String path) {
+		throw new MalformedRequestException("Deleting elements is not supported");
+	}
+
+	@Override
+	public Object put(String path, Object data) {
+		throw new MalformedRequestException("Setting elements is not supported");
+	}
+
+	@Override
+	public Object patch(String path, Object data) {
+		throw new MalformedRequestException("Patching elements is not supported");
+	}
+}
diff --git a/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/provider/aas/WrapperAsset.java b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/provider/aas/WrapperAsset.java
new file mode 100644
index 0000000..f69cbc7
--- /dev/null
+++ b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/provider/aas/WrapperAsset.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.wrapper.provider.aas;
+
+import org.eclipse.basyx.aas.metamodel.api.parts.asset.AssetKind;
+import org.eclipse.basyx.aas.metamodel.map.parts.Asset;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+
+/**
+ * Dummy asset for the wrapper AAS interface
+ * 
+ * @author espen
+ *
+ */
+public class WrapperAsset extends Asset {
+	public WrapperAsset() {
+		setIdShort("WrapperAsset");
+		setIdentification(IdentifierType.CUSTOM, "WrapperAsset");
+		setAssetKind(AssetKind.INSTANCE);
+	}
+}
diff --git a/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/provider/aas/WrapperAssetAdministrationShell.java b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/provider/aas/WrapperAssetAdministrationShell.java
new file mode 100644
index 0000000..9e3c77a
--- /dev/null
+++ b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/provider/aas/WrapperAssetAdministrationShell.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.wrapper.provider.aas;
+
+import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+
+/**
+ * Dummy AAS for the wrapper AAS interface
+ * 
+ * @author espen
+ *
+ */
+public class WrapperAssetAdministrationShell extends AssetAdministrationShell {
+	public WrapperAssetAdministrationShell() {
+		setIdShort("WrapperAAS");
+		setIdentification(IdentifierType.CUSTOM, "WrapperAAS");
+	}
+}
diff --git a/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/provider/aas/WrapperSubmodel.java b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/provider/aas/WrapperSubmodel.java
new file mode 100644
index 0000000..d539a21
--- /dev/null
+++ b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/provider/aas/WrapperSubmodel.java
@@ -0,0 +1,122 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.wrapper.provider.aas;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyType;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation;
+import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaProviderHelper;
+import org.eclipse.basyx.wrapper.receiver.IPropertyWrapperService;
+import org.eclipse.basyx.wrapper.receiver.PropertyResult;
+import org.eclipse.basyx.wrapper.receiver.configuration.PropertyConfiguration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A submodel for wrapping the data
+ * 
+ * @author espen
+ *
+ */
+public class WrapperSubmodel extends Submodel {
+	private static final Logger logger = LoggerFactory.getLogger(WrapperSubmodel.class);
+
+	protected Map<String, SubmodelElementCollection> collections = new HashMap<>();
+	private IPropertyWrapperService proxyService;
+
+	public WrapperSubmodel(String idShort, IIdentifier id, IPropertyWrapperService connector,
+			Collection<PropertyConfiguration> config) {
+		super();
+		setIdShort(idShort);
+		setIdentification(id.getIdType(), id.getId());
+		setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, true, "0112/2///61360_4#AAF891#001", KeyType.IRDI)));
+
+		proxyService = connector;
+		proxyService.addProxyListener((String propId, PropertyResult result) -> {
+			SubmodelElementCollection coll = collections.get(propId);
+			if (coll != null) {
+				Collection<ISubmodelElement> smElements = generateSubmodelElements(propId, result);
+				coll.setValue(smElements);
+			} else {
+				logger.error("Invalid property '" + propId + "' has been updated");
+			}
+		});
+		initialize(config, connector);
+	}
+
+	private void initialize(Collection<PropertyConfiguration> configs, IPropertyWrapperService connector) {
+		for ( PropertyConfiguration config : configs ) {
+			String propId = config.getId();
+			if ( config.getActive() ) {
+				setActiveProperty(propId);
+			} else {
+				setPassiveProperty(propId);		
+			}
+		}
+	}
+
+	private Collection<ISubmodelElement> generateSubmodelElements(String idShort, PropertyResult result) {
+		Collection<ISubmodelElement> elements = new ArrayList<>();
+		List<Object> data = result.getData();
+		List<String> dates = result.getTimestamps();
+		for (int i = data.size() - 1; i >= 0; i--) {
+			Property dateProp = new Property();
+			dateProp.setIdShort("time" + i);
+			dateProp.setValue(dates.get(i).toString());
+			elements.add(dateProp);
+			Property valueProp = new Property();
+			valueProp.setIdShort("value" + i);
+			valueProp.setValue(data.get(i));
+			elements.add(valueProp);
+		}
+		Operation setOperation = new Operation();
+		setOperation.setIdShort("set" + idShort);
+		Function<Object[], Object> fillInvokable = (params) -> {
+			// not supported, yet
+			return params;
+		};
+		setOperation.setInvokable(fillInvokable);
+		elements.add(setOperation);
+		return elements;
+	}
+
+	private void setActiveProperty(String propId) {
+		SubmodelElementCollection coll = new SubmodelElementCollection();
+		coll.setIdShort(propId);
+		collections.put(propId, coll);
+		addSubmodelElement(coll);
+	}
+
+	private void setPassiveProperty(final String propId) {
+		SubmodelElementCollection coll = new SubmodelElementCollection();
+		coll.setIdShort(propId);
+		collections.put(propId, new SubmodelElementCollection());
+		addSubmodelElement(coll);
+
+		coll.put(Property.VALUE, VABLambdaProviderHelper.createSimple(() -> {
+			proxyService.generatePassiveValue(propId);
+			return collections.get(propId).getValue();
+		}, null));
+	}
+}
diff --git a/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/provider/grafana/GrafanaProvider.java b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/provider/grafana/GrafanaProvider.java
new file mode 100644
index 0000000..041401f
--- /dev/null
+++ b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/provider/grafana/GrafanaProvider.java
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.wrapper.provider.grafana;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import org.eclipse.basyx.wrapper.provider.GenericWrapperProvider;
+import org.eclipse.basyx.wrapper.receiver.PropertyResult;
+
+/**
+ * Grafana-specific proxy provider. Is based on a SimpleJson interface for grafana
+ * 
+ * @author espen
+ */
+public class GrafanaProvider extends GenericWrapperProvider {
+	public static final String TYPE = "GRAFANA";
+
+	public GrafanaProvider() {
+		this.providerPath = "/grafana";
+	}
+
+	@Override
+	public Object get(String path) {
+		return true;
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public Object post(String path, Object value) {
+		path = preparePath(path);
+
+		String idShort = null;
+		if (path.equals("search")) {
+			Map<String, Object> request = (Map<String, Object>) value;
+			idShort = (String) request.get("target");
+			Set<String> results = getSearchResults(idShort);
+			return results;
+		} else if (path.equals("query")) {
+			Map<String, Object> request = (Map<String, Object>) value;
+			List<Object> targets = (List<Object>) request.get("targets");
+			Map<String, Object> targetMap = (Map<String, Object>) targets.get(0);
+			idShort = (String) targetMap.get("target");
+		}
+
+		if (idShort == null || idShort.isEmpty()) {
+			return false;
+		}
+
+		PropertyResult result = (PropertyResult) super.get(idShort);
+		GrafanaTimeseries response = new GrafanaTimeseries();
+		response.addTarget(idShort, result);
+		return response;
+	}
+
+	private Set<String> getSearchResults(String term) {
+		Set<String> validProperties = proxyService.getValidProperties();
+		return validProperties.stream()
+				.filter(s -> s.toLowerCase().contains(term.toLowerCase()))
+				.collect(Collectors.toSet());
+	}
+}
diff --git a/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/provider/grafana/GrafanaTimeseries.java b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/provider/grafana/GrafanaTimeseries.java
new file mode 100644
index 0000000..ebd18a5
--- /dev/null
+++ b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/provider/grafana/GrafanaTimeseries.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.wrapper.provider.grafana;
+
+import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.basyx.wrapper.receiver.PropertyResult;
+
+/**
+ * Conversion class for Grafana timeseries response
+ * 
+ * @author espen
+ *
+ */
+public class GrafanaTimeseries extends ArrayList<Object> {
+	private static final long serialVersionUID = 1L;
+	public GrafanaTimeseries() {
+		super();
+	}
+
+	public void addTarget(String idShort, PropertyResult result) {
+		Map<String, Object> targetData = new HashMap<>();
+		
+		List<Object> values = result.getData();
+		List<String> timestamps = result.getTimestamps();
+		List<List<Object>> dataPoints = new ArrayList<>(values.size());
+		for ( int i = 0; i < values.size(); i++ ) {
+			List<Object> entry = new ArrayList<>(2);
+			entry.add(values.get(i));
+			try {
+				Date date = PropertyResult.DATE_FORMAT.parse(timestamps.get(i));
+				long ms = date.getTime();
+				entry.add(ms);
+			} catch (ParseException e) {
+				e.printStackTrace();
+				break;
+			}
+			// entry.add(Integer.parseInt(timestamps.get(i))); // add string formatted timestamp
+			dataPoints.add(entry);
+		}
+		targetData.put("target", idShort);
+		targetData.put("datapoints", dataPoints);
+		this.add(targetData);
+	}
+}
diff --git a/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/provider/streamsheets/StreamsheetsProvider.java b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/provider/streamsheets/StreamsheetsProvider.java
new file mode 100644
index 0000000..5c0ca5b
--- /dev/null
+++ b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/provider/streamsheets/StreamsheetsProvider.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.wrapper.provider.streamsheets;
+
+import org.eclipse.basyx.wrapper.provider.GenericWrapperProvider;
+
+/**
+ * Streamsheets-specific proxy provider
+ * 
+ * @author espen
+ */
+public class StreamsheetsProvider extends GenericWrapperProvider {
+	public static final String TYPE = "STREAMSHEETS";
+
+	public StreamsheetsProvider() {
+		this.providerPath = "/streamsheets";
+	}
+}
diff --git a/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/receiver/DataPoint.java b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/receiver/DataPoint.java
new file mode 100644
index 0000000..fe6ba96
--- /dev/null
+++ b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/receiver/DataPoint.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.wrapper.receiver;
+
+import java.util.Date;
+
+/**
+ * Represents a single datapoint for a property
+ * 
+ * @author espen
+ *
+ */
+public class DataPoint {
+    private Date timestamp;
+    private Object value;
+
+	public DataPoint(Object value) {
+		this.timestamp = new Date();
+		this.value = value;
+	}
+
+    public DataPoint(Date timestamp, Object value) {
+        this.timestamp = timestamp;
+        this.value = value;
+    }
+
+    public Date getTimestamp() {
+        return timestamp;
+    }
+
+    public void setTimestamp(Date timestamp) {
+        this.timestamp = timestamp;
+    }
+
+    public Object getValue() {
+        return value;
+    }
+
+    public void setValue(Object value) {
+        this.value = value;
+    }
+}
diff --git a/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/receiver/IPropertyEndpoint.java b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/receiver/IPropertyEndpoint.java
new file mode 100644
index 0000000..41f0c6d
--- /dev/null
+++ b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/receiver/IPropertyEndpoint.java
@@ -0,0 +1,22 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.wrapper.receiver;
+
+/**
+ * Represents a single property endpoint
+ * 
+ * @author espen
+ *
+ */
+public interface IPropertyEndpoint {
+	public DataPoint retrieveValue();
+
+	public void setValue(Object newValue);
+}
diff --git a/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/receiver/IPropertyWrapperService.java b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/receiver/IPropertyWrapperService.java
new file mode 100644
index 0000000..08a4145
--- /dev/null
+++ b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/receiver/IPropertyWrapperService.java
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.wrapper.receiver;
+
+import java.util.Set;
+
+import org.eclipse.basyx.wrapper.receiver.configuration.PropertyConfiguration;
+
+/**
+ * Interface for a property service to get and set properties
+ * 
+ * @author espen
+ *
+ */
+public interface IPropertyWrapperService {
+	/**
+	 * Adds a property configuration to the service
+	 * 
+	 * @param config
+	 */
+	public void addPropertyConfig(PropertyConfiguration config);
+
+	/**
+	 * Returns a list of valid properties that have been configured
+	 */
+	public Set<String> getValidProperties();
+
+	/**
+	 * Gets the current result for a property
+	 * 
+	 * @param propId
+	 * @return
+	 */
+	public PropertyResult getPropertyValue(String propId);
+
+	/**
+	 * Explicitely generates a new value for a passive property.
+	 * 
+	 * @param propId
+	 * @return
+	 */
+	public void generatePassiveValue(String propId);
+
+	/**
+	 * Sets a remote data point to a new value
+	 * 
+	 * @param propId
+	 * @param newValue
+	 */
+	public void setPropertyValue(String propId, Object newValue);
+
+	public void addProxyListener(IWrapperListener listener);
+
+	/**
+	 * Start collecting data for all active properties
+	 */
+	public void start();
+
+	/**
+	 * Stop collecting data for all active properties
+	 */
+	public void stop();
+}
diff --git a/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/receiver/IWrapperListener.java b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/receiver/IWrapperListener.java
new file mode 100644
index 0000000..5040d05
--- /dev/null
+++ b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/receiver/IWrapperListener.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.wrapper.receiver;
+
+/**
+ * A listener for values that have been generated by the wrapper
+ * 
+ * @author espen
+ *
+ */
+public interface IWrapperListener {
+	/**
+	 * Informs the listener about a new value that has been generated
+	 * 
+	 * @param result
+	 */
+	public void newValue(String propId, PropertyResult result);
+}
diff --git a/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/receiver/PropertyResult.java b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/receiver/PropertyResult.java
new file mode 100644
index 0000000..a947aa1
--- /dev/null
+++ b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/receiver/PropertyResult.java
@@ -0,0 +1,88 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.wrapper.receiver;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * Represents a property result with multiple datapoints
+ * 
+ * @author espen
+ *
+ */
+public class PropertyResult extends HashMap<String, Object> {
+	private static final long serialVersionUID = 1L;
+	public static final String CONTENT = "content";
+	public static final String DATES = "timestamp";
+	public static final String TITLE = "title";
+	public static final String SUCCESS = "success";
+
+	protected int maxValues = 10;
+	protected List<Object> content = new ArrayList<>();
+	// VAB can't serialize dates, yet
+	protected List<String> timestamp = new ArrayList<>();
+
+	public static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
+
+	public PropertyResult(String title, int maxValues) {
+		this.maxValues = maxValues;
+		put(CONTENT, content);
+		put(DATES, timestamp);
+		put(SUCCESS, true);
+		put(TITLE, "Value of property '" + title + "'");
+	}
+
+	public PropertyResult(PropertyResult clone) {
+		this.maxValues = clone.maxValues;
+		content = new ArrayList<>(clone.getData());
+		timestamp = new ArrayList<>(clone.getTimestamps());
+		put(CONTENT, content);
+		put(DATES, timestamp);
+		put(SUCCESS, clone.getSuccess());
+		put(TITLE, "Value of property '" + clone.getTitle() + "'");
+	}
+
+	public void setSuccess(boolean success) {
+		put(SUCCESS, success);
+	}
+
+	public boolean getSuccess() {
+		return (boolean) get(SUCCESS);
+	}
+
+	public void setTitle(String title) {
+		put(TITLE, title);
+	}
+
+	public String getTitle() {
+		return (String) get(TITLE);
+	}
+
+	public List<Object> getData() {
+		return content;
+	}
+
+	public List<String> getTimestamps() {
+		return timestamp;
+	}
+
+	public synchronized void addDataPoint(DataPoint value) {
+		content.add(value.getValue());
+		timestamp.add(DATE_FORMAT.format(value.getTimestamp()));
+		while (content.size() > maxValues) {
+			content.remove(0);
+			timestamp.remove(0);
+		}
+	}
+}
diff --git a/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/receiver/SeparateAASService.java b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/receiver/SeparateAASService.java
new file mode 100644
index 0000000..48c0ef7
--- /dev/null
+++ b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/receiver/SeparateAASService.java
@@ -0,0 +1,223 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.wrapper.receiver;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
+import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.dataelement.ConnectedProperty;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.eclipse.basyx.submodel.restapi.MultiSubmodelElementProvider;
+import org.eclipse.basyx.vab.factory.java.ModelProxyFactory;
+import org.eclipse.basyx.vab.modelprovider.VABPathTools;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorFactory;
+import org.eclipse.basyx.wrapper.exception.WrapperRequestException;
+import org.eclipse.basyx.wrapper.receiver.configuration.AASPropertyConfiguration;
+import org.eclipse.basyx.wrapper.receiver.configuration.PropertyConfiguration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Wrapper service for seperately querying the configured properties.
+ * 
+ * @author espen
+ *
+ */
+public class SeparateAASService implements IPropertyWrapperService {
+	private static final Logger logger = LoggerFactory.getLogger(SeparateAASService.class);
+
+	// Registry
+	protected IAASRegistry registry;
+
+	// Property configurations
+	protected Map<String, String> aasIds = new HashMap<>();
+	protected Map<String, String> submodelIds = new HashMap<>();
+	protected Map<String, String> shortIds = new HashMap<>();
+	protected Map<String, Integer> maxValues = new HashMap<>();
+	protected Set<String> activeProperties = new HashSet<>();
+
+	// Current data
+	protected Map<String, PropertyResult> propertyResults = new HashMap<>();
+
+	// Additional
+	protected Map<String, String> submodelCachedEndpoints = new HashMap<>();
+	protected Map<String, Thread> threads = new HashMap<>();
+	protected List<IWrapperListener> listeners = new ArrayList<>();
+
+	public SeparateAASService(IAASRegistry registry, Collection<PropertyConfiguration> configs) {
+		this.registry = registry;
+		configs.forEach(this::addPropertyConfig);
+	}
+
+	@Override
+	public void addPropertyConfig(PropertyConfiguration config) {
+		if (config instanceof AASPropertyConfiguration) {
+			AASPropertyConfiguration aasConfig = (AASPropertyConfiguration) config;
+
+			String propId = config.getId();
+			logger.info("Initialize " + propId);
+			aasIds.put(propId, aasConfig.getAAS());
+			submodelIds.put(propId, aasConfig.getSubmodel());
+			shortIds.put(propId, aasConfig.getShortId());
+			propertyResults.put(propId, new PropertyResult(propId, config.getMaxValues()));
+			if (config.getActive()) {
+				activeProperties.add(propId);
+				int interval = config.getInterval(); // => in ms
+				threads.put(propId, createPropertyThread(propId, interval));
+			}
+		}
+	}
+
+	private AASDescriptor getAASDescriptorFromRegistry(String aasId) {
+		// Assume custom AAS identifier => aas identifier type doesn't really matter for lookup
+		IIdentifier aasIdentifier = new Identifier(IdentifierType.CUSTOM, aasId);
+		return registry.lookupAAS(aasIdentifier);
+	}
+
+	private String getSubmodelEndpoint(String aasId, String submodelId) {
+		String aasSmId = aasId + "::" + submodelId;
+		String smEndpoint = submodelCachedEndpoints.get(aasSmId);
+
+		if (smEndpoint == null) {
+			// Retrieve AAS descriptor from the registry to parse the submodel endpoint
+			try {
+				AASDescriptor aasDescriptor = getAASDescriptorFromRegistry(aasId);
+				SubmodelDescriptor smDescriptor = aasDescriptor.getSubmodelDescriptorFromIdShort(submodelId);
+
+				if (smDescriptor == null) {
+					throw new WrapperRequestException("Could not look up descriptor for SubModel '" + submodelId
+							+ "' since it does not exist in AAS '" + aasId + "'");
+				}
+
+				smEndpoint = smDescriptor.getFirstEndpoint();
+
+				// Cache retrieved submodel endpoints
+				submodelCachedEndpoints.put(aasSmId, smEndpoint);
+			} catch (Exception e) {
+				throw new WrapperRequestException("Could not look up descriptor for AAS '" + aasId
+						+ "' since it does not exist or is not available");
+			}
+		}
+
+		return smEndpoint;
+	}
+
+	private IProperty getConnectedProperty(String smEndpoint, String shortId) {
+		// Build the property address from that (and assume it's there)
+		String propEndpoint = VABPathTools.concatenatePaths(smEndpoint, MultiSubmodelElementProvider.ELEMENTS, shortId);
+
+		// Create a "ConnectedProperty" that gives access to the property
+		ModelProxyFactory mpf = new ModelProxyFactory(new HTTPConnectorFactory());
+		return new ConnectedProperty(mpf.createProxy(propEndpoint));
+	}
+
+	private Object getSinglePropertyValue(String propId) {
+		try {
+			String aasId = aasIds.get(propId);
+			String submodelId = submodelIds.get(propId);
+			String shortId = shortIds.get(propId);
+			String smEndpoint = getSubmodelEndpoint(aasId, submodelId);
+			IProperty property = getConnectedProperty(smEndpoint, shortId);
+			return property.getValue();
+		} catch (Exception e) {
+			throw new WrapperRequestException(e.getLocalizedMessage(), e);
+		}
+	}
+
+	@Override
+	public PropertyResult getPropertyValue(String propId) {
+		// Clone a result to prevent changes in the returned value
+		return new PropertyResult(propertyResults.get(propId));
+	}
+
+	@Override
+	public void setPropertyValue(String propId, Object newValue) {
+		try {
+			String aasId = aasIds.get(propId);
+			String submodelId = submodelIds.get(propId);
+			String shortId = shortIds.get(propId);
+			String smEndpoint = getSubmodelEndpoint(aasId, submodelId);
+			IProperty property = getConnectedProperty(smEndpoint, shortId);
+			property.setValue(newValue);
+		} catch (Exception e) {
+			throw new WrapperRequestException(e.getLocalizedMessage(), e);
+		}
+	}
+
+	@Override
+	public void generatePassiveValue(String propId) {
+		if (activeProperties.contains(propId)) {
+			throw new WrapperRequestException("Property with id '" + propId + "' is active");
+		}
+		retrieveValue(propId);
+	}
+
+	private Thread createPropertyThread(final String propId, final int intervalTime) {
+		return new Thread(() -> {
+			Thread thisThread = Thread.currentThread();
+			while (thisThread == threads.get(propId)) {
+				retrieveValue(propId);
+				try {
+					Thread.sleep(intervalTime);
+				} catch (InterruptedException e) {
+				}
+			}
+		});
+	}
+
+	private void retrieveValue(String propId) {
+		PropertyResult values = propertyResults.get(propId);
+		if (values == null) {
+			throw new WrapperRequestException("Property with id '" + propId + "' does not exist");
+		}
+		Object newValue = getSinglePropertyValue(propId);
+		DataPoint dataPoint = new DataPoint(newValue);
+		values.addDataPoint(dataPoint);
+
+		// inform listeners
+		for (IWrapperListener listener : listeners) {
+			listener.newValue(propId, new PropertyResult(values));
+		}
+	}
+
+	@Override
+	public void start() {
+		logger.info("Starting " + threads.size() + " threads");
+		for (Thread t : threads.values()) {
+			t.start();
+		}
+	}
+
+	@Override
+	public void stop() {
+		threads.clear();
+	}
+
+	@Override
+	public void addProxyListener(IWrapperListener listener) {
+		this.listeners.add(listener);
+	}
+
+	@Override
+	public Set<String> getValidProperties() {
+		return propertyResults.keySet();
+	}
+}
diff --git a/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/receiver/configuration/AASPropertyConfiguration.java b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/receiver/configuration/AASPropertyConfiguration.java
new file mode 100644
index 0000000..46c50f1
--- /dev/null
+++ b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/receiver/configuration/AASPropertyConfiguration.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.wrapper.receiver.configuration;
+
+/**
+ * Represents a single configuration for a property. The datasource for this
+ * property is an AAS property.
+ * 
+ * @author espen
+ *
+ */
+public class AASPropertyConfiguration extends PropertyConfiguration {
+	private static final long serialVersionUID = 1L;
+
+	public static final String TYPE = "AAS";
+
+	// indices in the configuration file
+	public static final String AAS = "aas";
+	public static final String SUBMODEL = "submodel";
+	public static final String SHORTID = "shortId";
+
+	public AASPropertyConfiguration() {
+		super();
+	}
+
+	public AASPropertyConfiguration(PropertyConfiguration config) {
+		putAll(config);
+	}
+
+	public String getAAS() {
+		return get(AAS);
+	}
+
+	public void setAAS(String aas) {
+		put(AAS, aas);
+	}
+
+	public String getSubmodel() {
+		return get(SUBMODEL);
+	}
+
+	public void setSubmodel(String submodel) {
+		put(SUBMODEL, submodel);
+	}
+
+	public String getShortId() {
+		return get(SHORTID);
+	}
+
+	public void setShortId(String shortId) {
+		put(SHORTID, shortId);
+	}
+}
diff --git a/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/receiver/configuration/PropertyConfiguration.java b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/receiver/configuration/PropertyConfiguration.java
new file mode 100644
index 0000000..460777e
--- /dev/null
+++ b/examples/basyx.aasWrapper/src/main/java/org/eclipse/basyx/wrapper/receiver/configuration/PropertyConfiguration.java
@@ -0,0 +1,93 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.wrapper.receiver.configuration;
+
+import java.util.HashMap;
+import java.util.StringJoiner;
+
+/**
+ * Represents a single configuration for a proxy property. 
+ * 
+ * @author espen
+ *
+ */
+public class PropertyConfiguration extends HashMap<String, String> {
+	private static final long serialVersionUID = 1L;
+
+	// configuration indices
+	public static final String INDEX = "properties";
+	public static final String ID = "id";
+	public static final String TYPE = "type";
+	public static final String ACTIVE = "active";
+	public static final String INTERVAL = "interval";
+	public static final String MAX_VALUES = "maxValues";
+
+	public boolean getActive() {
+		return "true".equals(get(ACTIVE));
+	}
+
+	public void setActive(Boolean active) {
+		put(ACTIVE, active.toString());
+	}
+
+	/**
+	 * Get active update interval in ms
+	 * 
+	 * @return
+	 */
+	public int getInterval() {
+		if (get(INTERVAL) != null) {
+			return Integer.parseInt(get(INTERVAL));
+		} else {
+			return 0;
+		}
+	}
+
+	public void setInterval(int interval) {
+		put(INTERVAL, String.valueOf(interval));
+	}
+
+	public int getMaxValues() {
+		if (get(MAX_VALUES) != null) {
+			return Integer.parseInt(get(MAX_VALUES));
+		} else {
+			return 1;
+		}
+	}
+
+	public void setMaxValues(int maxValues) {
+		put(INTERVAL, String.valueOf(maxValues));
+	}
+
+	public String getId() {
+		return get(ID);
+	}
+
+	public void setId(String id) {
+		put(ID, id);
+	}
+
+	public String getType() {
+		return get(TYPE);
+	}
+
+	public void setType(String type) {
+		put(TYPE, type);
+	}
+
+	@Override
+	public String toString() {
+		StringJoiner joiner = new StringJoiner(", ");
+		entrySet().forEach((Entry<String, String> e) -> {
+			joiner.add(e.getKey() + "=" + e.getValue());
+		});
+		return "{ " + joiner.toString() + " }";
+	}
+}
diff --git a/examples/basyx.aasWrapper/src/main/resources/context.properties b/examples/basyx.aasWrapper/src/main/resources/context.properties
new file mode 100644
index 0000000..6429487
--- /dev/null
+++ b/examples/basyx.aasWrapper/src/main/resources/context.properties
@@ -0,0 +1,17 @@
+# ###############################
+# HTTP Context configuration file
+# ###############################
+
+# ###############################
+# Context Path
+# ###############################
+# Specifies the subpath in the url for this server context
+ 
+contextPath=/
+
+# ###############################
+# Port
+# ###############################
+# Specifies the port for this server context
+
+contextPort=6500
\ No newline at end of file
diff --git a/examples/basyx.aasWrapper/src/main/resources/wrapper.properties b/examples/basyx.aasWrapper/src/main/resources/wrapper.properties
new file mode 100644
index 0000000..957dc39
--- /dev/null
+++ b/examples/basyx.aasWrapper/src/main/resources/wrapper.properties
@@ -0,0 +1,25 @@
+registry.endpoint=http://registry:4000/registry/
+
+properties.temp.type=AAS
+properties.temp.active=true
+properties.temp.aas=DashboardAAS
+properties.temp.submodel=DashboardSubmodel
+properties.temp.shortId=temperature
+properties.temp.interval=1000
+properties.temp.maxValues=10
+
+properties.dummy.type=AAS
+properties.dummy.active=false
+properties.dummy.aas=DashboardAAS
+properties.dummy.submodel=DashboardSubmodel
+properties.dummy.shortId=dummy
+properties.dummy.maxValues=3
+
+providers.simplified.type=STREAMSHEETS
+providers.simplified.path=/streamsheets
+
+providers.aas.type=AAS
+providers.aas.path=/proxyAAS
+
+providers.asdf.type=GRAFANA
+providers.asdf.path=/grafana
diff --git a/examples/basyx.aasWrapper/src/test/resources/.env b/examples/basyx.aasWrapper/src/test/resources/.env
new file mode 100644
index 0000000..4ca39a7
--- /dev/null
+++ b/examples/basyx.aasWrapper/src/test/resources/.env
@@ -0,0 +1,39 @@
+# ##################
+# Docker Environment
+# ##################
+
+# ##################
+# Host Port
+# ##################
+# Specifies the port for the Docker HOST the container port is mapped to
+
+BASYX_HOST_PORT=6500
+
+# ##################
+# Container Port
+# ##################
+# Specifies the port for the Docker CONTAINER that is be mapped for the host 
+
+BASYX_CONTAINER_PORT=6500
+
+# ##################
+# Image Name
+# ##################
+# The image of the image that is build for this component
+
+BASYX_IMAGE_NAME=basyx/aas-wrapper
+
+# ##################
+# Image Tag
+# ##################
+# The image tag of the image that is build for this component
+
+BASYX_IMAGE_TAG=1.0.0
+
+# ##################
+# Container Name
+# ##################
+# The name of the container used for the default environment
+ 
+BASYX_CONTAINER_NAME=aas-wrapper
+
diff --git a/examples/basyx.aasWrapper/start.bat b/examples/basyx.aasWrapper/start.bat
new file mode 100644
index 0000000..7d0dc6c
--- /dev/null
+++ b/examples/basyx.aasWrapper/start.bat
@@ -0,0 +1 @@
+docker-compose up
\ No newline at end of file
diff --git a/examples/basyx.aasWrapper/start.sh b/examples/basyx.aasWrapper/start.sh
new file mode 100644
index 0000000..d935e43
--- /dev/null
+++ b/examples/basyx.aasWrapper/start.sh
@@ -0,0 +1,2 @@
+#!/usr/bin/env sh
+docker-compose up
\ No newline at end of file
diff --git a/examples/basyx.aasWrapper/stop.bat b/examples/basyx.aasWrapper/stop.bat
new file mode 100644
index 0000000..58694d0
--- /dev/null
+++ b/examples/basyx.aasWrapper/stop.bat
@@ -0,0 +1 @@
+docker-compose down
\ No newline at end of file
diff --git a/examples/basyx.aasWrapper/stop.sh b/examples/basyx.aasWrapper/stop.sh
new file mode 100644
index 0000000..f5139e2
--- /dev/null
+++ b/examples/basyx.aasWrapper/stop.sh
@@ -0,0 +1,2 @@
+#!/usr/bin/env sh
+docker-compose down
\ No newline at end of file
diff --git a/examples/basyx.dashboardAAS/.gitignore b/examples/basyx.dashboardAAS/.gitignore
new file mode 100644
index 0000000..02eeb17
--- /dev/null
+++ b/examples/basyx.dashboardAAS/.gitignore
@@ -0,0 +1,69 @@
+.classpath
+.project
+
+regressiontest/
+target/
+pom.xml.tag
+pom.xml.releaseBackup
+pom.xml.versionsBackup
+pom.xml.next
+release.properties
+dependency-reduced-pom.xml
+buildNumber.properties
+.mvn/timing.properties
+.mvn/wrapper/maven-wrapper.jar
+.metadata
+bin/
+tmp/
+*.tmp
+*.bak
+*.swp
+*~.nib
+local.properties
+.settings/
+.loadpath
+.recommenders
+
+# External tool builders
+.externalToolBuilders/
+
+# Locally stored "Eclipse launch configurations"
+*.launch
+
+# PyDev specific (Python IDE for Eclipse)
+*.pydevproject
+
+# CDT-specific (C/C++ Development Tooling)
+.cproject
+
+# CDT- autotools
+.autotools
+
+# Java annotation processor (APT)
+.factorypath
+
+# PDT-specific (PHP Development Tools)
+.buildpath
+
+# sbteclipse plugin
+.target
+
+# Tern plugin
+.tern-project
+
+# TeXlipse plugin
+.texlipse
+
+# STS (Spring Tool Suite)
+.springBeans
+
+# Code Recommenders
+.recommenders/
+
+# Annotation Processing
+.apt_generated/
+
+# Scala IDE specific (Scala & Java development for Eclipse)
+.cache-main
+.scala_dependencies
+.worksheet
\ No newline at end of file
diff --git a/examples/basyx.dashboardAAS/Dockerfile b/examples/basyx.dashboardAAS/Dockerfile
new file mode 100644
index 0000000..1a26b27
--- /dev/null
+++ b/examples/basyx.dashboardAAS/Dockerfile
@@ -0,0 +1,23 @@
+# Add java runtime environment for execution
+FROM java:8-jdk-alpine 
+
+# Copy built jar to image using the jar name specified in the pom.xml (JAR_FILE)
+ARG JAR_FILE
+COPY target/${JAR_FILE} /usr/share/basyxExecutable.jar
+COPY target/lib /usr/share/lib
+COPY src/main/resources/context.properties /usr/share/config/context.properties
+COPY src/main/resources/dashboardsubmodel.properties /usr/share/config/dashboardsubmodel.properties
+
+# Expose the appropriate port. In case of Tomcat, this is 8080.
+ARG PORT
+EXPOSE ${PORT}
+
+# Set the path for the context configuration file
+ARG CONTEXT_CONFIG_KEY
+ENV ${CONTEXT_CONFIG_KEY} "/usr/share/config/context.properties"
+
+# Set the path for the submodel config
+ENV BASYX_DASHBOARDSUBMODEL "/usr/share/config/dashboardsubmodel.properties"
+ 
+# Start the jar
+CMD java -jar "/usr/share/basyxExecutable.jar"
\ No newline at end of file
diff --git a/examples/basyx.dashboardAAS/build.bat b/examples/basyx.dashboardAAS/build.bat
new file mode 100644
index 0000000..0977f37
--- /dev/null
+++ b/examples/basyx.dashboardAAS/build.bat
@@ -0,0 +1 @@
+.././mvnw clean install -U -Pdocker
\ No newline at end of file
diff --git a/examples/basyx.dashboardAAS/build.sh b/examples/basyx.dashboardAAS/build.sh
new file mode 100644
index 0000000..d223f82
--- /dev/null
+++ b/examples/basyx.dashboardAAS/build.sh
@@ -0,0 +1,2 @@
+#!/usr/bin/env sh
+.././mvnw clean install -U -Pdocker -DskipTests
\ No newline at end of file
diff --git a/examples/basyx.dashboardAAS/docker-compose.yml b/examples/basyx.dashboardAAS/docker-compose.yml
new file mode 100644
index 0000000..a52f474
--- /dev/null
+++ b/examples/basyx.dashboardAAS/docker-compose.yml
@@ -0,0 +1,17 @@
+version: '3'
+services:
+
+  registry:
+    image: eclipsebasyx/aas-registry:1.0.1
+    container_name: dashboard-registry
+    ports:
+      - 4000:4000
+
+  dashboard-aas:
+    image: eclipsebasyx/dashboard-aas:0.1.0-SNAPSHOT
+    container_name: dashboard-aas
+    environment:
+      - BaSyxDashboardSubmodel_Min=15
+#      - BaSyxDashboardSubmodel_Max=30
+    ports:
+      - 6400:6400
\ No newline at end of file
diff --git a/examples/basyx.dashboardAAS/pom.xml b/examples/basyx.dashboardAAS/pom.xml
new file mode 100644
index 0000000..183dff4
--- /dev/null
+++ b/examples/basyx.dashboardAAS/pom.xml
@@ -0,0 +1,66 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<parent>
+		<groupId>org.eclipse.basyx</groupId>
+		<artifactId>basyx.components.docker</artifactId>
+		<version>1.0.0</version>
+	</parent>
+	
+	<artifactId>basyx.components.dashboardAAS</artifactId>
+	<name>BaSyx Dashboard AAS</name>
+	
+	<properties>
+		<!--  
+			basyx.components.executable is the executable class with the definition of the public void main(String[]).
+			It is needed when building the jar in the maven-jar-plugin (see basyx.components.docker/pom.xml) 
+		-->
+		<basyx.components.executable>org.eclipse.basyx.dashboard.AASExecutable</basyx.components.executable>
+	</properties>
+	
+	<packaging>jar</packaging>
+	
+	<!-- Define additional plugins that are not included by default -->
+	<!-- Plugin configuration is done in parent project(s) -->
+	<build>
+		<plugins>
+			<!-- Attach sources to jar file -->
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-source-plugin</artifactId>
+			</plugin>
+		</plugins>
+	</build>
+	
+	<profiles>
+		<profile>
+			<!-- 
+				"Docker" profile - do not build & install docker images by default
+				Run "mvn install -Pdocker" in order to include docker  
+			-->
+			<id>docker</id>
+			<build>
+				<plugins>
+					<!-- Read maven properties from file -->
+					<plugin>
+						<groupId>org.codehaus.mojo</groupId>
+						<artifactId>properties-maven-plugin</artifactId>
+					</plugin>
+				
+					<!-- Copy the dependencies necessary to run the jar -->
+					<plugin>
+						<groupId>org.apache.maven.plugins</groupId>
+						<artifactId>maven-dependency-plugin</artifactId>
+					</plugin>
+				
+					<!-- Build the docker image -->
+					<plugin>
+						<groupId>com.spotify</groupId>
+						<artifactId>dockerfile-maven-plugin</artifactId>
+					</plugin>
+				</plugins>
+			</build>
+		</profile>
+	</profiles>
+</project>
\ No newline at end of file
diff --git a/examples/basyx.dashboardAAS/src/main/java/org/eclipse/basyx/dashboard/AASExecutable.java b/examples/basyx.dashboardAAS/src/main/java/org/eclipse/basyx/dashboard/AASExecutable.java
new file mode 100644
index 0000000..3f03e3d
--- /dev/null
+++ b/examples/basyx.dashboardAAS/src/main/java/org/eclipse/basyx/dashboard/AASExecutable.java
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.dashboard;
+
+import java.util.ArrayList;
+
+import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
+import org.eclipse.basyx.aas.metamodel.map.parts.Asset;
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
+import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
+import org.eclipse.basyx.aas.restapi.AASModelProvider;
+import org.eclipse.basyx.aas.restapi.MultiSubmodelProvider;
+import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.restapi.SubmodelProvider;
+import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
+import org.eclipse.basyx.vab.protocol.http.server.BaSyxHTTPServer;
+import org.eclipse.basyx.vab.protocol.http.server.BaSyxContext;
+import org.eclipse.basyx.vab.protocol.http.server.VABHTTPInterface;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Executable for a very basic, dynamic AAS, that is meant to be used in an example about how
+ * to integrate properties of "real" AAS in a dashboard.
+ * 
+ * @author espen
+ *
+ */
+public class AASExecutable {
+	private static final Logger logger = LoggerFactory.getLogger(AASExecutable.class);
+
+	public static final String HOST = "dashboard-aas";
+	public static final int PORT = 6400;
+	public static final String REGISTRY_ENDPOINT = "http://registry:4000/registry/";
+
+	public static void main(String[] args) throws Exception {
+		// Use docker-compose health check for registry instead
+		Thread.sleep(3000);
+
+		logger.info("Creating AAS...");
+		AssetAdministrationShell aas = new DashboardAssetAdministrationShell();
+		Asset asset = new DashboardAsset();
+		aas.setAsset(asset);
+		Submodel sm = new DashboardSubmodel();
+		aas.setConceptDictionary(new ArrayList<>());
+		aas.addSubmodel(sm);
+		
+		logger.info("Starting aas servlet...");
+		createServlet(aas, sm);
+		logger.info("Registering aas...");
+		AASDescriptor descriptor = new AASDescriptor(aas, "http://" + HOST + ":" + PORT + "/aas");
+		descriptor.addSubmodelDescriptor(
+				new SubmodelDescriptor(sm, "http://" + HOST + ":" + PORT + "/aas/submodels/DashboardSubmodel/"));
+		registerAAS(descriptor, REGISTRY_ENDPOINT);
+
+		logger.info("Finished");
+	}
+
+	private static void registerAAS(AASDescriptor descriptor, String registryEndpoint) throws InterruptedException {
+		IAASRegistry registry = new AASRegistryProxy(registryEndpoint);
+		// Quick & dirty, try to register until registry is up
+		for (int i = 0; i < 10; i++) {
+			try {
+				registry.register(descriptor);
+				break;
+			} catch (Exception e) {
+				Thread.sleep(2000);
+			}
+		}
+	}
+
+	private static void createServlet(AssetAdministrationShell aas, Submodel... submodels) {
+		MultiSubmodelProvider provider = new MultiSubmodelProvider();
+		provider.setAssetAdministrationShell(new AASModelProvider(aas));
+		for (Submodel sm : submodels) {
+			provider.addSubmodel(new SubmodelProvider(sm));
+		}
+		BaSyxContextConfiguration config = new BaSyxContextConfiguration();
+		config.loadFromDefaultSource();
+		BaSyxContext context = config.createBaSyxContext();
+		context.addServletMapping("/*", new VABHTTPInterface<IModelProvider>(provider));
+        BaSyxHTTPServer server = new BaSyxHTTPServer(context);
+		server.start();
+	}
+}
diff --git a/examples/basyx.dashboardAAS/src/main/java/org/eclipse/basyx/dashboard/DashboardAsset.java b/examples/basyx.dashboardAAS/src/main/java/org/eclipse/basyx/dashboard/DashboardAsset.java
new file mode 100644
index 0000000..747c6b5
--- /dev/null
+++ b/examples/basyx.dashboardAAS/src/main/java/org/eclipse/basyx/dashboard/DashboardAsset.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.dashboard;
+
+import org.eclipse.basyx.aas.metamodel.api.parts.asset.AssetKind;
+import org.eclipse.basyx.aas.metamodel.map.parts.Asset;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+
+/**
+ * A dummy Asset for the dashboar AAS
+ * 
+ * @author espen
+ *
+ */
+public class DashboardAsset extends Asset {
+	public DashboardAsset() {
+		setIdShort("DashboardAsset");
+		setIdentification(IdentifierType.CUSTOM, "DashboardAsset");
+		setAssetKind(AssetKind.INSTANCE);
+	}
+}
diff --git a/examples/basyx.dashboardAAS/src/main/java/org/eclipse/basyx/dashboard/DashboardAssetAdministrationShell.java b/examples/basyx.dashboardAAS/src/main/java/org/eclipse/basyx/dashboard/DashboardAssetAdministrationShell.java
new file mode 100644
index 0000000..71d4407
--- /dev/null
+++ b/examples/basyx.dashboardAAS/src/main/java/org/eclipse/basyx/dashboard/DashboardAssetAdministrationShell.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.dashboard;
+
+import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+
+/**
+ * A minimal AAS header for the dashboard AAS
+ * 
+ * @author espen
+ *
+ */
+public class DashboardAssetAdministrationShell extends AssetAdministrationShell {
+	public DashboardAssetAdministrationShell() {
+		setIdShort("DashboardAAS");
+		setIdentification(IdentifierType.CUSTOM, "DashboardAAS");
+	}
+}
diff --git a/examples/basyx.dashboardAAS/src/main/java/org/eclipse/basyx/dashboard/DashboardSubmodel.java b/examples/basyx.dashboardAAS/src/main/java/org/eclipse/basyx/dashboard/DashboardSubmodel.java
new file mode 100644
index 0000000..c342810
--- /dev/null
+++ b/examples/basyx.dashboardAAS/src/main/java/org/eclipse/basyx/dashboard/DashboardSubmodel.java
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.dashboard;
+
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyType;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaProviderHelper;
+
+/**
+ * Dummy Submodel with two dynamic values. A configurable temperature value that randomly
+ * returns values in a specific range. And a random boolean value.
+ * 
+ * @author espen
+ *
+ */
+public class DashboardSubmodel extends Submodel {
+	private int minValue;
+	private int maxValue;
+
+	public DashboardSubmodel() {
+		setIdShort("DashboardSubmodel");
+		setIdentification(IdentifierType.CUSTOM, "DashboardTemperatureSubmodel");
+		setSemanticId(new Reference(
+				new Key(KeyElements.CONCEPTDESCRIPTION, true, "0112/2///61360_4#AAF891#001", KeyType.IRDI)));
+		setTemperatureProperty();
+		setDummyProperty();
+
+		DashboardSubmodelConfiguration config = new DashboardSubmodelConfiguration();
+		config.loadFromDefaultSource();
+		minValue = config.getMin();
+		maxValue = config.getMax();
+	}
+
+	private void setTemperatureProperty() {
+		Property temperatureProperty = new Property();
+		temperatureProperty.setIdShort("temperature");
+		temperatureProperty.set(VABLambdaProviderHelper.createSimple(() -> {
+			return Math.random() * (maxValue - minValue) + minValue;
+		}, null), ValueType.Double);
+		// Adds a reference to a semantic ID to specify the property semantics (see CDD)
+		// Ref by identifier:
+		Key key = new Key(KeyElements.CONCEPTDESCRIPTION, true, "0112/2///61360_4#AAF891#001", KeyType.IRDI);
+		IReference refByIdentifier = new Reference(key);
+		temperatureProperty.setSemanticId(refByIdentifier);
+		addSubmodelElement(temperatureProperty);
+	}
+
+	private void setDummyProperty() {
+		Property dummyProperty = new Property();
+		dummyProperty.setIdShort("dummy");
+		dummyProperty.set(VABLambdaProviderHelper.createSimple(() -> {
+			return (Math.random() > 0.5);
+		}, null), ValueType.Boolean);
+		addSubmodelElement(dummyProperty);
+	}
+}
diff --git a/examples/basyx.dashboardAAS/src/main/java/org/eclipse/basyx/dashboard/DashboardSubmodelConfiguration.java b/examples/basyx.dashboardAAS/src/main/java/org/eclipse/basyx/dashboard/DashboardSubmodelConfiguration.java
new file mode 100644
index 0000000..f2c3c97
--- /dev/null
+++ b/examples/basyx.dashboardAAS/src/main/java/org/eclipse/basyx/dashboard/DashboardSubmodelConfiguration.java
@@ -0,0 +1,98 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.dashboard;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.basyx.components.configuration.BaSyxConfiguration;
+
+/**
+ * Simple configuration for setting minimal and maxmimal values for the dashboard submodel
+ * 
+ * @author espen
+ *
+ */
+public class DashboardSubmodelConfiguration extends BaSyxConfiguration {
+	// Prefix for environment variables
+	public static final String ENV_PREFIX = "BaSyxDashboardSubmodel_";
+
+	// Default BaSyx Context configuration
+	public static final int DEFAULT_MIN = 10;
+	public static final int DEFAULT_MAX = 30;
+
+	public static final String MIN = "Min";
+	public static final String MAX = "Max";
+
+	// The default path for the context properties file
+	public static final String DEFAULT_CONFIG_PATH = "dashboardsubmodel.properties";
+
+	// The default key for variables pointing to the configuration file
+	public static final String DEFAULT_FILE_KEY = "BASYX_DASHBOARDSUBMODEL";
+
+	public static Map<String, String> getDefaultProperties() {
+		Map<String, String> defaultProps = new HashMap<>();
+		defaultProps.put(MIN, Integer.toString(DEFAULT_MIN));
+		defaultProps.put(MAX, Integer.toString(DEFAULT_MAX));
+		return defaultProps;
+	}
+
+	/**
+	 * Empty Constructor - use default values
+	 */
+	public DashboardSubmodelConfiguration() {
+		super(getDefaultProperties());
+	}
+
+	/**
+	 * Constructor with predefined value map
+	 */
+	public DashboardSubmodelConfiguration(Map<String, String> values) {
+		super(values);
+	}
+
+	/**
+	 * Constructor with initial configuration - docBasePath and hostname are default values
+	 * 
+	 * @param min The minimal temperature value
+	 * @param max The maximal temperature value
+	 */
+	public DashboardSubmodelConfiguration(int min, int max) {
+		this();
+		setMin(min);
+		setMax(max);
+	}
+
+	public void loadFromEnvironmentVariables() {
+		String[] properties = { MIN, MAX };
+		loadFromEnvironmentVariables(ENV_PREFIX, properties);
+	}
+
+	public void loadFromDefaultSource() {
+		loadFileOrDefaultResource(DEFAULT_FILE_KEY, DEFAULT_CONFIG_PATH);
+		loadFromEnvironmentVariables();
+	}
+
+	public void setMin(int min) {
+		setProperty(MIN, Integer.toString(min));
+	}
+
+	public void setMax(int max) {
+		setProperty(MIN, Integer.toString(max));
+	}
+
+	public int getMin() {
+		return Integer.parseInt(getProperty(MIN));
+	}
+
+	public int getMax() {
+		return Integer.parseInt(getProperty(MAX));
+	}
+}
diff --git a/examples/basyx.dashboardAAS/src/main/resources/context.properties b/examples/basyx.dashboardAAS/src/main/resources/context.properties
new file mode 100644
index 0000000..9e4461a
--- /dev/null
+++ b/examples/basyx.dashboardAAS/src/main/resources/context.properties
@@ -0,0 +1,17 @@
+# ###############################
+# HTTP Context configuration file
+# ###############################
+
+# ###############################
+# Context Path
+# ###############################
+# Specifies the subpath in the url for this server context
+ 
+contextPath=/
+
+# ###############################
+# Port
+# ###############################
+# Specifies the port for this server context
+
+contextPort=6400
\ No newline at end of file
diff --git a/examples/basyx.dashboardAAS/src/main/resources/dashboardsubmodel.properties b/examples/basyx.dashboardAAS/src/main/resources/dashboardsubmodel.properties
new file mode 100644
index 0000000..63bbaa6
--- /dev/null
+++ b/examples/basyx.dashboardAAS/src/main/resources/dashboardsubmodel.properties
@@ -0,0 +1,17 @@
+# ###############################
+# Dashboard submodel configuration
+# ###############################
+
+# ###############################
+# Min temperature value
+# ###############################
+# Specifies the min value for the dynamic random temperature
+ 
+Min=10
+
+# ###############################
+# Max temperature value
+# ###############################
+# Specifies the max value for the dynamic random temperature
+
+Max=30
\ No newline at end of file
diff --git a/examples/basyx.dashboardAAS/src/test/resources/.env b/examples/basyx.dashboardAAS/src/test/resources/.env
new file mode 100644
index 0000000..f71a8db
--- /dev/null
+++ b/examples/basyx.dashboardAAS/src/test/resources/.env
@@ -0,0 +1,39 @@
+# ##################
+# Docker Environment
+# ##################
+
+# ##################
+# Host Port
+# ##################
+# Specifies the port for the Docker HOST the container port is mapped to
+
+BASYX_HOST_PORT=6400
+
+# ##################
+# Container Port
+# ##################
+# Specifies the port for the Docker CONTAINER that is be mapped for the host 
+
+BASYX_CONTAINER_PORT=6400
+
+# ##################
+# Image Name
+# ##################
+# The image of the image that is build for this component
+
+BASYX_IMAGE_NAME=basyx/dashboard-aas
+
+# ##################
+# Image Tag
+# ##################
+# The image tag of the image that is build for this component
+
+BASYX_IMAGE_TAG=1.0.0
+
+# ##################
+# Container Name
+# ##################
+# The name of the container used for the default environment
+ 
+BASYX_CONTAINER_NAME=dashboard-aas
+
diff --git a/examples/basyx.dashboardAAS/start.bat b/examples/basyx.dashboardAAS/start.bat
new file mode 100644
index 0000000..7d0dc6c
--- /dev/null
+++ b/examples/basyx.dashboardAAS/start.bat
@@ -0,0 +1 @@
+docker-compose up
\ No newline at end of file
diff --git a/examples/basyx.dashboardAAS/start.sh b/examples/basyx.dashboardAAS/start.sh
new file mode 100644
index 0000000..d935e43
--- /dev/null
+++ b/examples/basyx.dashboardAAS/start.sh
@@ -0,0 +1,2 @@
+#!/usr/bin/env sh
+docker-compose up
\ No newline at end of file
diff --git a/examples/basyx.dashboardAAS/stop.bat b/examples/basyx.dashboardAAS/stop.bat
new file mode 100644
index 0000000..58694d0
--- /dev/null
+++ b/examples/basyx.dashboardAAS/stop.bat
@@ -0,0 +1 @@
+docker-compose down
\ No newline at end of file
diff --git a/examples/basyx.dashboardAAS/stop.sh b/examples/basyx.dashboardAAS/stop.sh
new file mode 100644
index 0000000..f5139e2
--- /dev/null
+++ b/examples/basyx.dashboardAAS/stop.sh
@@ -0,0 +1,2 @@
+#!/usr/bin/env sh
+docker-compose down
\ No newline at end of file
diff --git a/examples/basyx.grafana/.gitignore b/examples/basyx.grafana/.gitignore
new file mode 100644
index 0000000..a5271c0
--- /dev/null
+++ b/examples/basyx.grafana/.gitignore
@@ -0,0 +1 @@
+/lib/plugins/*
\ No newline at end of file
diff --git a/examples/basyx.grafana/dashboard.json b/examples/basyx.grafana/dashboard.json
new file mode 100644
index 0000000..624f1a5
--- /dev/null
+++ b/examples/basyx.grafana/dashboard.json
@@ -0,0 +1,110 @@
+{
+  "annotations": {
+    "list": [
+      {
+        "builtIn": 1,
+        "datasource": "-- Grafana --",
+        "enable": true,
+        "hide": true,
+        "iconColor": "rgba(0, 211, 255, 1)",
+        "name": "Annotations & Alerts",
+        "type": "dashboard"
+      }
+    ]
+  },
+  "editable": true,
+  "gnetId": null,
+  "graphTooltip": 0,
+  "id": 1,
+  "links": [],
+  "panels": [
+    {
+      "datasource": null,
+      "description": "",
+      "fieldConfig": {
+        "defaults": {
+          "color": {
+            "mode": "thresholds"
+          },
+          "custom": {},
+          "mappings": [],
+          "min": 0,
+          "thresholds": {
+            "mode": "absolute",
+            "steps": [
+              {
+                "color": "green",
+                "value": null
+              },
+              {
+                "color": "#EAB839",
+                "value": 20
+              },
+              {
+                "color": "red",
+                "value": 27
+              }
+            ]
+          },
+          "unit": "celsius"
+        },
+        "overrides": []
+      },
+      "gridPos": {
+        "h": 8,
+        "w": 6,
+        "x": 0,
+        "y": 0
+      },
+      "id": 2,
+      "options": {
+        "colorMode": "value",
+        "graphMode": "area",
+        "justifyMode": "auto",
+        "orientation": "auto",
+        "reduceOptions": {
+          "calcs": [
+            "lastNotNull"
+          ],
+          "fields": "",
+          "values": false
+        },
+        "text": {},
+        "textMode": "auto"
+      },
+      "pluginVersion": "7.4.0",
+      "targets": [
+        {
+          "refId": "A",
+          "target": "temp",
+          "type": "timeserie"
+        }
+      ],
+      "timeFrom": null,
+      "timeShift": null,
+      "title": "Temperature",
+      "transparent": true,
+      "type": "stat"
+    }
+  ],
+  "refresh": "1s",
+  "schemaVersion": 27,
+  "style": "dark",
+  "tags": [],
+  "templating": {
+    "list": []
+  },
+  "time": {
+    "from": "now-10s",
+    "to": "now"
+  },
+  "timepicker": {
+    "refresh_intervals": [
+      "1s"
+    ]
+  },
+  "timezone": "",
+  "title": "BaSyx Temperature",
+  "uid": "forkaVEGz",
+  "version": 5
+}
\ No newline at end of file
diff --git a/examples/basyx.grafana/docker-compose.yml b/examples/basyx.grafana/docker-compose.yml
new file mode 100644
index 0000000..81b38ac
--- /dev/null
+++ b/examples/basyx.grafana/docker-compose.yml
@@ -0,0 +1,32 @@
+version: '2.1'
+services:
+
+  registry:
+    image: eclipsebasyx/aas-registry:1.0.1
+    container_name: dashboard-registry
+    ports:
+      - 4000:4000
+
+  dashboard-aas:
+    image: eclipsebasyx/dashboard-aas:0.1.0-SNAPSHOT
+    container_name: dashboard-aas
+    environment:
+      - BaSyxDashboardSubmodel_Min=15
+#      - BaSyxDashboardSubmodel_Max=30
+    ports:
+      - 6400:6400
+
+  aas-wrapper:
+    image: eclipsebasyx/aas-wrapper:0.1.0-SNAPSHOT
+    container_name: aas-wrapper
+    ports:
+      - 6500:6500
+
+  grafana:
+    image: grafana/grafana:7.4.0
+    container_name: grafana
+    ports:
+      - 3000:3000
+    volumes:
+      - ./lib:/var/lib/grafana
+      - ./grafana.ini:/etc/grafana/grafana.ini
\ No newline at end of file
diff --git a/examples/basyx.grafana/grafana.ini b/examples/basyx.grafana/grafana.ini
new file mode 100644
index 0000000..098e757
--- /dev/null
+++ b/examples/basyx.grafana/grafana.ini
@@ -0,0 +1,902 @@
+##################### Grafana Configuration Defaults #####################
+#
+# Do not modify this file in grafana installs
+#
+
+# possible values : production, development
+app_mode = production
+
+# instance name, defaults to HOSTNAME environment variable value or hostname if HOSTNAME var is empty
+instance_name = ${HOSTNAME}
+
+#################################### Paths ###############################
+[paths]
+# Path to where grafana can store temp files, sessions, and the sqlite3 db (if that is used)
+data = data
+
+# Temporary files in `data` directory older than given duration will be removed
+temp_data_lifetime = 24h
+
+# Directory where grafana can store logs
+logs = data/log
+
+# Directory where grafana will automatically scan and look for plugins
+plugins = data/plugins
+
+# folder that contains provisioning config files that grafana will apply on startup and while running.
+provisioning = conf/provisioning
+
+#################################### Server ##############################
+[server]
+# Protocol (http, https, h2, socket)
+protocol = http
+
+# The ip address to bind to, empty will bind to all interfaces
+http_addr =
+
+# The http port to use
+http_port = 3000
+
+# The public facing domain name used to access grafana from a browser
+domain = localhost
+
+# Redirect to correct domain if host header does not match domain
+# Prevents DNS rebinding attacks
+enforce_domain = false
+
+# The full public facing url
+root_url = %(protocol)s://%(domain)s:%(http_port)s/
+
+# Serve Grafana from subpath specified in `root_url` setting. By default it is set to `false` for compatibility reasons.
+serve_from_sub_path = false
+
+# Log web requests
+router_logging = false
+
+# the path relative working path
+static_root_path = public
+
+# enable gzip
+enable_gzip = false
+
+# https certs & key file
+cert_file =
+cert_key =
+
+# Unix socket path
+socket = /tmp/grafana.sock
+
+# CDN Url
+cdn_url =
+
+#################################### Database ############################
+[database]
+# You can configure the database connection by specifying type, host, name, user and password
+# as separate properties or as on string using the url property.
+
+# Either "mysql", "postgres" or "sqlite3", it's your choice
+type = sqlite3
+host = 127.0.0.1:3306
+name = grafana
+user = root
+# If the password contains # or ; you have to wrap it with triple quotes. Ex """#password;"""
+password =
+# Use either URL or the previous fields to configure the database
+# Example: mysql://user:secret@host:port/database
+url =
+
+# Max idle conn setting default is 2
+max_idle_conn = 2
+
+# Max conn setting default is 0 (mean not set)
+max_open_conn =
+
+# Connection Max Lifetime default is 14400 (means 14400 seconds or 4 hours)
+conn_max_lifetime = 14400
+
+# Set to true to log the sql calls and execution times.
+log_queries =
+
+# For "postgres", use either "disable", "require" or "verify-full"
+# For "mysql", use either "true", "false", or "skip-verify".
+ssl_mode = disable
+
+ca_cert_path =
+client_key_path =
+client_cert_path =
+server_cert_name =
+
+# For "sqlite3" only, path relative to data_path setting
+path = grafana.db
+
+# For "sqlite3" only. cache mode setting used for connecting to the database
+cache_mode = private
+
+#################################### Cache server #############################
+[remote_cache]
+# Either "redis", "memcached" or "database" default is "database"
+type = database
+
+# cache connectionstring options
+# database: will use Grafana primary database.
+# redis: config like redis server e.g. `addr=127.0.0.1:6379,pool_size=100,db=0,ssl=false`. Only addr is required. ssl may be 'true', 'false', or 'insecure'.
+# memcache: 127.0.0.1:11211
+connstr =
+
+#################################### Data proxy ###########################
+[dataproxy]
+
+# This enables data proxy logging, default is false
+logging = false
+
+# How long the data proxy waits before timing out, default is 30 seconds.
+# This setting also applies to core backend HTTP data sources where query requests use an HTTP client with timeout set.
+timeout = 30
+
+# How many seconds the data proxy waits before sending a keepalive request.
+keep_alive_seconds = 30
+
+# How many seconds the data proxy waits for a successful TLS Handshake before timing out.
+tls_handshake_timeout_seconds = 10
+
+# How many seconds the data proxy will wait for a server's first response headers after
+# fully writing the request headers if the request has an "Expect: 100-continue"
+# header. A value of 0 will result in the body being sent immediately, without
+# waiting for the server to approve.
+expect_continue_timeout_seconds = 1
+
+# The maximum number of idle connections that Grafana will keep alive.
+max_idle_connections = 100
+
+# How many seconds the data proxy keeps an idle connection open before timing out.
+idle_conn_timeout_seconds = 90
+
+# If enabled and user is not anonymous, data proxy will add X-Grafana-User header with username into the request.
+send_user_header = false
+
+#################################### Analytics ###########################
+[analytics]
+# Server reporting, sends usage counters to stats.grafana.org every 24 hours.
+# No ip addresses are being tracked, only simple counters to track
+# running instances, dashboard and error counts. It is very helpful to us.
+# Change this option to false to disable reporting.
+reporting_enabled = true
+
+# Set to false to disable all checks to https://grafana.com
+# for new versions (grafana itself and plugins), check is used
+# in some UI views to notify that grafana or plugin update exists
+# This option does not cause any auto updates, nor send any information
+# only a GET request to https://grafana.com to get latest versions
+check_for_updates = true
+
+# Google Analytics universal tracking code, only enabled if you specify an id here
+google_analytics_ua_id =
+
+# Google Tag Manager ID, only enabled if you specify an id here
+google_tag_manager_id =
+
+#################################### Security ############################
+[security]
+# disable creation of admin user on first start of grafana
+disable_initial_admin_creation = false
+
+# default admin user, created on startup
+admin_user = admin
+
+# default admin password, can be changed before first start of grafana, or in profile settings
+admin_password = admin
+
+# used for signing
+secret_key = SW2YcwTIb9zpOOhoPsMm
+
+# disable gravatar profile images
+disable_gravatar = false
+
+# data source proxy whitelist (ip_or_domain:port separated by spaces)
+data_source_proxy_whitelist =
+
+# disable protection against brute force login attempts
+disable_brute_force_login_protection = false
+
+# set to true if you host Grafana behind HTTPS. default is false.
+cookie_secure = false
+
+# set cookie SameSite attribute. defaults to `lax`. can be set to "lax", "strict", "none" and "disabled"
+cookie_samesite = lax
+
+# set to true if you want to allow browsers to render Grafana in a <frame>, <iframe>, <embed> or <object>. default is false.
+allow_embedding = false
+
+# Set to true if you want to enable http strict transport security (HSTS) response header.
+# This is only sent when HTTPS is enabled in this configuration.
+# HSTS tells browsers that the site should only be accessed using HTTPS.
+strict_transport_security = false
+
+# Sets how long a browser should cache HSTS. Only applied if strict_transport_security is enabled.
+strict_transport_security_max_age_seconds = 86400
+
+# Set to true if to enable HSTS preloading option. Only applied if strict_transport_security is enabled.
+strict_transport_security_preload = false
+
+# Set to true if to enable the HSTS includeSubDomains option. Only applied if strict_transport_security is enabled.
+strict_transport_security_subdomains = false
+
+# Set to true to enable the X-Content-Type-Options response header.
+# The X-Content-Type-Options response HTTP header is a marker used by the server to indicate that the MIME types advertised
+# in the Content-Type headers should not be changed and be followed.
+x_content_type_options = true
+
+# Set to true to enable the X-XSS-Protection header, which tells browsers to stop pages from loading
+# when they detect reflected cross-site scripting (XSS) attacks.
+x_xss_protection = true
+
+# Enable adding the Content-Security-Policy header to your requests.
+# CSP allows to control resources the user agent is allowed to load and helps prevent XSS attacks.
+content_security_policy = false
+
+# Set Content Security Policy template used when adding the Content-Security-Policy header to your requests.
+# $NONCE in the template includes a random nonce.
+content_security_policy_template = """script-src 'unsafe-eval' 'strict-dynamic' $NONCE;object-src 'none';font-src 'self';style-src 'self' 'unsafe-inline';img-src 'self' data:;base-uri 'self';connect-src 'self' grafana.com;manifest-src 'self';media-src 'none';form-action 'self';"""
+
+#################################### Snapshots ###########################
+[snapshots]
+# snapshot sharing options
+external_enabled = true
+external_snapshot_url = https://snapshots-origin.raintank.io
+external_snapshot_name = Publish to snapshot.raintank.io
+
+# Set to true to enable this Grafana instance act as an external snapshot server and allow unauthenticated requests for
+# creating and deleting snapshots.
+public_mode = false
+
+# remove expired snapshot
+snapshot_remove_expired = true
+
+#################################### Dashboards ##################
+
+[dashboards]
+# Number dashboard versions to keep (per dashboard). Default: 20, Minimum: 1
+versions_to_keep = 20
+
+# Minimum dashboard refresh interval. When set, this will restrict users to set the refresh interval of a dashboard lower than given interval. Per default this is 5 seconds.
+# The interval string is a possibly signed sequence of decimal numbers, followed by a unit suffix (ms, s, m, h, d), e.g. 30s or 1m.
+min_refresh_interval = 1s
+
+# Path to the default home dashboard. If this value is empty, then Grafana uses StaticRootPath + "dashboards/home.json"
+default_home_dashboard_path =
+
+################################### Data sources #########################
+[datasources]
+# Upper limit of data sources that Grafana will return. This limit is a temporary configuration and it will be deprecated when pagination will be introduced on the list data sources API.
+datasource_limit = 5000
+
+#################################### Users ###############################
+[users]
+# disable user signup / registration
+allow_sign_up = false
+
+# Allow non admin users to create organizations
+allow_org_create = false
+
+# Set to true to automatically assign new users to the default organization (id 1)
+auto_assign_org = true
+
+# Set this value to automatically add new users to the provided organization (if auto_assign_org above is set to true)
+auto_assign_org_id = 1
+
+# Default role new users will be automatically assigned (if auto_assign_org above is set to true)
+auto_assign_org_role = Viewer
+
+# Require email validation before sign up completes
+verify_email_enabled = false
+
+# Background text for the user field on the login page
+login_hint = email or username
+password_hint = password
+
+# Default UI theme ("dark" or "light")
+default_theme = dark
+
+# External user management
+external_manage_link_url =
+external_manage_link_name =
+external_manage_info =
+
+# Viewers can edit/inspect dashboard settings in the browser. But not save the dashboard.
+viewers_can_edit = false
+
+# Editors can administrate dashboard, folders and teams they create
+editors_can_admin = false
+
+# The duration in time a user invitation remains valid before expiring. This setting should be expressed as a duration. Examples: 6h (hours), 2d (days), 1w (week). Default is 24h (24 hours). The minimum supported duration is 15m (15 minutes).
+user_invite_max_lifetime_duration = 24h
+
+# Enter a comma-separated list of usernames to hide them in the Grafana UI. These users are shown to Grafana admins and to themselves.
+hidden_users =
+
+[auth]
+# Login cookie name
+login_cookie_name = grafana_session
+
+# The maximum lifetime (duration) an authenticated user can be inactive before being required to login at next visit. Default is 7 days (7d). This setting should be expressed as a duration, e.g. 5m (minutes), 6h (hours), 10d (days), 2w (weeks), 1M (month). The lifetime resets at each successful token rotation (token_rotation_interval_minutes).
+login_maximum_inactive_lifetime_duration =
+
+# The maximum lifetime (duration) an authenticated user can be logged in since login time before being required to login. Default is 30 days (30d). This setting should be expressed as a duration, e.g. 5m (minutes), 6h (hours), 10d (days), 2w (weeks), 1M (month).
+login_maximum_lifetime_duration =
+
+# How often should auth tokens be rotated for authenticated users when being active. The default is each 10 minutes.
+token_rotation_interval_minutes = 10
+
+# Set to true to disable (hide) the login form, useful if you use OAuth
+disable_login_form = false
+
+# Set to true to disable the signout link in the side menu. useful if you use auth.proxy
+disable_signout_menu = false
+
+# URL to redirect the user to after sign out
+signout_redirect_url =
+
+# Set to true to attempt login with OAuth automatically, skipping the login screen.
+# This setting is ignored if multiple OAuth providers are configured.
+oauth_auto_login = false
+
+# OAuth state max age cookie duration in seconds. Defaults to 600 seconds.
+oauth_state_cookie_max_age = 600
+
+# limit of api_key seconds to live before expiration
+api_key_max_seconds_to_live = -1
+
+# Set to true to enable SigV4 authentication option for HTTP-based datasources
+sigv4_auth_enabled = false
+
+#################################### Anonymous Auth ######################
+[auth.anonymous]
+# enable anonymous access
+enabled = false
+
+# specify organization name that should be used for unauthenticated users
+org_name = Main Org.
+
+# specify role for unauthenticated users
+org_role = Viewer
+
+# mask the Grafana version number for unauthenticated users
+hide_version = false
+
+#################################### GitHub Auth #########################
+[auth.github]
+enabled = false
+allow_sign_up = true
+client_id = some_id
+client_secret =
+scopes = user:email,read:org
+auth_url = https://github.com/login/oauth/authorize
+token_url = https://github.com/login/oauth/access_token
+api_url = https://api.github.com/user
+allowed_domains =
+team_ids =
+allowed_organizations =
+
+#################################### GitLab Auth #########################
+[auth.gitlab]
+enabled = false
+allow_sign_up = true
+client_id = some_id
+client_secret =
+scopes = api
+auth_url = https://gitlab.com/oauth/authorize
+token_url = https://gitlab.com/oauth/token
+api_url = https://gitlab.com/api/v4
+allowed_domains =
+allowed_groups =
+
+#################################### Google Auth #########################
+[auth.google]
+enabled = false
+allow_sign_up = true
+client_id = some_client_id
+client_secret =
+scopes = https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email
+auth_url = https://accounts.google.com/o/oauth2/auth
+token_url = https://accounts.google.com/o/oauth2/token
+api_url = https://www.googleapis.com/oauth2/v1/userinfo
+allowed_domains =
+hosted_domain =
+
+#################################### Grafana.com Auth ####################
+# legacy key names (so they work in env variables)
+[auth.grafananet]
+enabled = false
+allow_sign_up = true
+client_id = some_id
+client_secret =
+scopes = user:email
+allowed_organizations =
+
+[auth.grafana_com]
+enabled = false
+allow_sign_up = true
+client_id = some_id
+client_secret =
+scopes = user:email
+allowed_organizations =
+
+#################################### Azure AD OAuth #######################
+[auth.azuread]
+name = Azure AD
+enabled = false
+allow_sign_up = true
+client_id = some_client_id
+client_secret =
+scopes = openid email profile
+auth_url = https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/authorize
+token_url = https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/token
+allowed_domains =
+allowed_groups =
+
+#################################### Okta OAuth #######################
+[auth.okta]
+name = Okta
+enabled = false
+allow_sign_up = true
+client_id = some_id
+client_secret =
+scopes = openid profile email groups
+auth_url = https://<tenant-id>.okta.com/oauth2/v1/authorize
+token_url = https://<tenant-id>.okta.com/oauth2/v1/token
+api_url = https://<tenant-id>.okta.com/oauth2/v1/userinfo
+allowed_domains =
+allowed_groups =
+role_attribute_path =
+
+#################################### Generic OAuth #######################
+[auth.generic_oauth]
+name = OAuth
+enabled = false
+allow_sign_up = true
+client_id = some_id
+client_secret =
+scopes = user:email
+email_attribute_name = email:primary
+email_attribute_path =
+login_attribute_path =
+name_attribute_path =
+role_attribute_path =
+id_token_attribute_name =
+auth_url =
+token_url =
+api_url =
+allowed_domains =
+team_ids =
+allowed_organizations =
+tls_skip_verify_insecure = false
+tls_client_cert =
+tls_client_key =
+tls_client_ca =
+
+#################################### Basic Auth ##########################
+[auth.basic]
+enabled = true
+
+#################################### Auth Proxy ##########################
+[auth.proxy]
+enabled = false
+header_name = X-WEBAUTH-USER
+header_property = username
+auto_sign_up = true
+# Deprecated, use sync_ttl instead
+ldap_sync_ttl = 60
+sync_ttl = 60
+whitelist =
+headers =
+enable_login_token = false
+
+#################################### Auth LDAP ###########################
+[auth.ldap]
+enabled = false
+config_file = /etc/grafana/ldap.toml
+allow_sign_up = true
+
+# LDAP background sync (Enterprise only)
+# At 1 am every day
+sync_cron = "0 0 1 * * *"
+active_sync_enabled = true
+
+#################################### SMTP / Emailing #####################
+[smtp]
+enabled = false
+host = localhost:25
+user =
+# If the password contains # or ; you have to wrap it with triple quotes. Ex """#password;"""
+password =
+cert_file =
+key_file =
+skip_verify = false
+from_address = admin@grafana.localhost
+from_name = Grafana
+ehlo_identity =
+startTLS_policy =
+
+[emails]
+welcome_email_on_sign_up = false
+templates_pattern = emails/*.html
+
+#################################### Logging ##########################
+[log]
+# Either "console", "file", "syslog". Default is console and file
+# Use space to separate multiple modes, e.g. "console file"
+mode = console file
+
+# Either "debug", "info", "warn", "error", "critical", default is "info"
+level = info
+
+# optional settings to set different levels for specific loggers. Ex filters = sqlstore:debug
+filters =
+
+# For "console" mode only
+[log.console]
+level =
+
+# log line format, valid options are text, console and json
+format = console
+
+# For "file" mode only
+[log.file]
+level =
+
+# log line format, valid options are text, console and json
+format = text
+
+# This enables automated log rotate(switch of following options), default is true
+log_rotate = true
+
+# Max line number of single file, default is 1000000
+max_lines = 1000000
+
+# Max size shift of single file, default is 28 means 1 << 28, 256MB
+max_size_shift = 28
+
+# Segment log daily, default is true
+daily_rotate = true
+
+# Expired days of log file(delete after max days), default is 7
+max_days = 7
+
+[log.syslog]
+level =
+
+# log line format, valid options are text, console and json
+format = text
+
+# Syslog network type and address. This can be udp, tcp, or unix. If left blank, the default unix endpoints will be used.
+network =
+address =
+
+# Syslog facility. user, daemon and local0 through local7 are valid.
+facility =
+
+# Syslog tag. By default, the process' argv[0] is used.
+tag =
+
+[log.frontend]
+# Should Sentry javascript agent be initialized
+enabled = false
+
+# Sentry DSN if you want to send events to Sentry.
+sentry_dsn =
+
+# Custom HTTP endpoint to send events captured by the Sentry agent to. Default will log the events to stdout.
+custom_endpoint = /log
+
+# Rate of events to be reported between 0 (none) and 1 (all), float
+sample_rate = 1.0
+
+# Requests per second limit enforced per an extended period, for Grafana backend log ingestion endpoint (/log).
+log_endpoint_requests_per_second_limit = 3
+
+# Max requests accepted per short interval of time for Grafana backend log ingestion endpoint (/log)
+log_endpoint_burst_limit = 15
+
+#################################### Usage Quotas ########################
+[quota]
+enabled = false
+
+#### set quotas to -1 to make unlimited. ####
+# limit number of users per Org.
+org_user = 10
+
+# limit number of dashboards per Org.
+org_dashboard = 100
+
+# limit number of data_sources per Org.
+org_data_source = 10
+
+# limit number of api_keys per Org.
+org_api_key = 10
+
+# limit number of orgs a user can create.
+user_org = 10
+
+# Global limit of users.
+global_user = -1
+
+# global limit of orgs.
+global_org = -1
+
+# global limit of dashboards
+global_dashboard = -1
+
+# global limit of api_keys
+global_api_key = -1
+
+# global limit on number of logged in users.
+global_session = -1
+
+#################################### Alerting ############################
+[alerting]
+# Disable alerting engine & UI features
+enabled = true
+# Makes it possible to turn off alert rule execution but alerting UI is visible
+execute_alerts = true
+
+# Default setting for new alert rules. Defaults to categorize error and timeouts as alerting. (alerting, keep_state)
+error_or_timeout = alerting
+
+# Default setting for how Grafana handles nodata or null values in alerting. (alerting, no_data, keep_state, ok)
+nodata_or_nullvalues = no_data
+
+# Alert notifications can include images, but rendering many images at the same time can overload the server
+# This limit will protect the server from render overloading and make sure notifications are sent out quickly
+concurrent_render_limit = 5
+
+# Default setting for alert calculation timeout. Default value is 30
+evaluation_timeout_seconds = 30
+
+# Default setting for alert notification timeout. Default value is 30
+notification_timeout_seconds = 30
+
+# Default setting for max attempts to sending alert notifications. Default value is 3
+max_attempts = 3
+
+# Makes it possible to enforce a minimal interval between evaluations, to reduce load on the backend
+min_interval_seconds = 1
+
+# Configures for how long alert annotations are stored. Default is 0, which keeps them forever.
+# This setting should be expressed as an duration. Ex 6h (hours), 10d (days), 2w (weeks), 1M (month).
+max_annotation_age =
+
+# Configures max number of alert annotations that Grafana stores. Default value is 0, which keeps all alert annotations.
+max_annotations_to_keep =
+
+#################################### Annotations #########################
+
+[annotations.dashboard]
+# Dashboard annotations means that annotations are associated with the dashboard they are created on.
+
+# Configures how long dashboard annotations are stored. Default is 0, which keeps them forever.
+# This setting should be expressed as a duration. Examples: 6h (hours), 10d (days), 2w (weeks), 1M (month).
+max_age =
+
+# Configures max number of dashboard annotations that Grafana stores. Default value is 0, which keeps all dashboard annotations.
+max_annotations_to_keep =
+
+[annotations.api]
+# API annotations means that the annotations have been created using the API without any
+# association with a dashboard.
+
+# Configures how long Grafana stores API annotations. Default is 0, which keeps them forever.
+# This setting should be expressed as a duration. Examples: 6h (hours), 10d (days), 2w (weeks), 1M (month).
+max_age =
+
+# Configures max number of API annotations that Grafana keeps. Default value is 0, which keeps all API annotations.
+max_annotations_to_keep =
+
+#################################### Explore #############################
+[explore]
+# Enable the Explore section
+enabled = true
+
+#################################### Internal Grafana Metrics ############
+# Metrics available at HTTP API Url /metrics
+[metrics]
+enabled              = true
+interval_seconds     = 10
+# Disable total stats (stat_totals_*) metrics to be generated
+disable_total_stats = false
+
+#If both are set, basic auth will be required for the metrics endpoint.
+basic_auth_username =
+basic_auth_password =
+
+# Metrics environment info adds dimensions to the `grafana_environment_info` metric, which
+# can expose more information about the Grafana instance.
+[metrics.environment_info]
+#exampleLabel1 = exampleValue1
+#exampleLabel2 = exampleValue2
+
+# Send internal Grafana metrics to graphite
+[metrics.graphite]
+# Enable by setting the address setting (ex localhost:2003)
+address =
+prefix = prod.grafana.%(instance_name)s.
+
+#################################### Grafana.com integration  ##########################
+[grafana_net]
+url = https://grafana.com
+
+[grafana_com]
+url = https://grafana.com
+
+#################################### Distributed tracing ############
+[tracing.jaeger]
+# jaeger destination (ex localhost:6831)
+address =
+# tag that will always be included in when creating new spans. ex (tag1:value1,tag2:value2)
+always_included_tag =
+# Type specifies the type of the sampler: const, probabilistic, rateLimiting, or remote
+sampler_type = const
+# jaeger samplerconfig param
+# for "const" sampler, 0 or 1 for always false/true respectively
+# for "probabilistic" sampler, a probability between 0 and 1
+# for "rateLimiting" sampler, the number of spans per second
+# for "remote" sampler, param is the same as for "probabilistic"
+# and indicates the initial sampling rate before the actual one
+# is received from the mothership
+sampler_param = 1
+# sampling_server_url is the URL of a sampling manager providing a sampling strategy.
+sampling_server_url =
+# Whether or not to use Zipkin span propagation (x-b3- HTTP headers).
+zipkin_propagation = false
+# Setting this to true disables shared RPC spans.
+# Not disabling is the most common setting when using Zipkin elsewhere in your infrastructure.
+disable_shared_zipkin_spans = false
+
+#################################### External Image Storage ##############
+[external_image_storage]
+# Used for uploading images to public servers so they can be included in slack/email messages.
+# You can choose between (s3, webdav, gcs, azure_blob, local)
+provider =
+
+[external_image_storage.s3]
+endpoint =
+path_style_access =
+bucket_url =
+bucket =
+region =
+path =
+access_key =
+secret_key =
+
+[external_image_storage.webdav]
+url =
+username =
+password =
+public_url =
+
+[external_image_storage.gcs]
+key_file =
+bucket =
+path =
+enable_signed_urls = false
+signed_url_expiration =
+
+[external_image_storage.azure_blob]
+account_name =
+account_key =
+container_name =
+
+[external_image_storage.local]
+# does not require any configuration
+
+[rendering]
+# Options to configure a remote HTTP image rendering service, e.g. using https://github.com/grafana/grafana-image-renderer.
+# URL to a remote HTTP image renderer service, e.g. http://localhost:8081/render, will enable Grafana to render panels and dashboards to PNG-images using HTTP requests to an external service.
+server_url =
+# If the remote HTTP image renderer service runs on a different server than the Grafana server you may have to configure this to a URL where Grafana is reachable, e.g. http://grafana.domain/.
+callback_url =
+# Concurrent render request limit affects when the /render HTTP endpoint is used. Rendering many images at the same time can overload the server,
+# which this setting can help protect against by only allowing a certain amount of concurrent requests.
+concurrent_render_request_limit = 30
+
+[panels]
+# here for to support old env variables, can remove after a few months
+enable_alpha = false
+disable_sanitize_html = false
+
+[plugins]
+enable_alpha = false
+app_tls_skip_verify_insecure = false
+# Enter a comma-separated list of plugin identifiers to identify plugins that are allowed to be loaded even if they lack a valid signature.
+allow_loading_unsigned_plugins =
+marketplace_url = https://grafana.com/grafana/plugins/
+
+#################################### Grafana Image Renderer Plugin ##########################
+[plugin.grafana-image-renderer]
+# Instruct headless browser instance to use a default timezone when not provided by Grafana, e.g. when rendering panel image of alert.
+# See ICU’s metaZones.txt (https://cs.chromium.org/chromium/src/third_party/icu/source/data/misc/metaZones.txt) for a list of supported
+# timezone IDs. Fallbacks to TZ environment variable if not set.
+rendering_timezone =
+
+# Instruct headless browser instance to use a default language when not provided by Grafana, e.g. when rendering panel image of alert.
+# Please refer to the HTTP header Accept-Language to understand how to format this value, e.g. 'fr-CH, fr;q=0.9, en;q=0.8, de;q=0.7, *;q=0.5'.
+rendering_language =
+
+# Instruct headless browser instance to use a default device scale factor when not provided by Grafana, e.g. when rendering panel image of alert.
+# Default is 1. Using a higher value will produce more detailed images (higher DPI), but will require more disk space to store an image.
+rendering_viewport_device_scale_factor =
+
+# Instruct headless browser instance whether to ignore HTTPS errors during navigation. Per default HTTPS errors are not ignored. Due to
+# the security risk it's not recommended to ignore HTTPS errors.
+rendering_ignore_https_errors =
+
+# Instruct headless browser instance whether to capture and log verbose information when rendering an image. Default is false and will
+# only capture and log error messages. When enabled, debug messages are captured and logged as well.
+# For the verbose information to be included in the Grafana server log you have to adjust the rendering log level to debug, configure
+# [log].filter = rendering:debug.
+rendering_verbose_logging =
+
+# Instruct headless browser instance whether to output its debug and error messages into running process of remote rendering service.
+# Default is false. This can be useful to enable (true) when troubleshooting.
+rendering_dumpio =
+
+# Additional arguments to pass to the headless browser instance. Default is --no-sandbox. The list of Chromium flags can be found
+# here (https://peter.sh/experiments/chromium-command-line-switches/). Multiple arguments is separated with comma-character.
+rendering_args =
+
+# You can configure the plugin to use a different browser binary instead of the pre-packaged version of Chromium.
+# Please note that this is not recommended, since you may encounter problems if the installed version of Chrome/Chromium is not
+# compatible with the plugin.
+rendering_chrome_bin =
+
+# Instruct how headless browser instances are created. Default is 'default' and will create a new browser instance on each request.
+# Mode 'clustered' will make sure that only a maximum of browsers/incognito pages can execute concurrently.
+# Mode 'reusable' will have one browser instance and will create a new incognito page on each request.
+rendering_mode =
+
+# When rendering_mode = clustered you can instruct how many browsers or incognito pages can execute concurrently. Default is 'browser'
+# and will cluster using browser instances.
+# Mode 'context' will cluster using incognito pages.
+rendering_clustering_mode =
+# When rendering_mode = clustered you can define maximum number of browser instances/incognito pages that can execute concurrently..
+rendering_clustering_max_concurrency =
+
+# Limit the maximum viewport width, height and device scale factor that can be requested.
+rendering_viewport_max_width =
+rendering_viewport_max_height =
+rendering_viewport_max_device_scale_factor =
+
+# Change the listening host and port of the gRPC server. Default host is 127.0.0.1 and default port is 0 and will automatically assign
+# a port not in use.
+grpc_host =
+grpc_port =
+
+[enterprise]
+license_path =
+
+[feature_toggles]
+# enable features, separated by spaces
+enable =
+
+[date_formats]
+# For information on what formatting patterns that are supported https://momentjs.com/docs/#/displaying/
+
+# Default system date format used in time range picker and other places where full time is displayed
+full_date = YYYY-MM-DD HH:mm:ss
+
+# Used by graph and other places where we only show small intervals
+interval_second = HH:mm:ss
+interval_minute = HH:mm
+interval_hour = MM/DD HH:mm
+interval_day = MM/DD
+interval_month = YYYY-MM
+interval_year = YYYY
+
+# Experimental feature
+use_browser_locale = false
+
+# Default timezone for user preferences. Options are 'browser' for the browser local timezone or a timezone name from IANA Time Zone database, e.g. 'UTC' or 'Europe/Amsterdam' etc.
+default_timezone = browser
+
+[expressions]
+# Enable or disable the expressions functionality.
+enabled = true
diff --git a/examples/basyx.grafana/lib/grafana.db b/examples/basyx.grafana/lib/grafana.db
new file mode 100644
index 0000000..3677257
--- /dev/null
+++ b/examples/basyx.grafana/lib/grafana.db
Binary files differ
diff --git a/examples/basyx.grafana/readme.txt b/examples/basyx.grafana/readme.txt
new file mode 100644
index 0000000..cd5669e
--- /dev/null
+++ b/examples/basyx.grafana/readme.txt
@@ -0,0 +1,28 @@
+HowTo: First Setup
+------------------
+
+1. Download SimpleJSON datasource from Grafana
+- Download .zip-file at
+	https://grafana.com/grafana/plugins/grafana-simple-json-datasource/installation
+- Unzip it in /lib/plugins:
+	/lib/plugins/grafana-simple-json-datasource/ should directly contain its files (e.g. package.json)
+
+2. Start docker-compose
+- Run "docker-compose up" in the /grafana/ folder
+
+3. Login (admin/admin)
+- http://localhost:3000/
+
+4. Add datasource
+- Configuration -> Datasources -> Add datasource -> Others: SimpleJson 
+
+5. Set URL Configuration in SimpleJson Datasource:
+URL -> http://aas-wrapper:6500/grafana/
+
+6. Import Dashboard
+- Dashboards -> Manage -> Import -> Upload dashboard.json
+
+7. Open BaSyx Dashboard
+- Dashboards -> Manage -> BaSyx Temperature
+- Optional: Set auto-refresh to 1s
+
diff --git a/examples/basyx.grafana/start.bat b/examples/basyx.grafana/start.bat
new file mode 100644
index 0000000..7d0dc6c
--- /dev/null
+++ b/examples/basyx.grafana/start.bat
@@ -0,0 +1 @@
+docker-compose up
\ No newline at end of file
diff --git a/examples/basyx.grafana/start.sh b/examples/basyx.grafana/start.sh
new file mode 100644
index 0000000..d935e43
--- /dev/null
+++ b/examples/basyx.grafana/start.sh
@@ -0,0 +1,2 @@
+#!/usr/bin/env sh
+docker-compose up
\ No newline at end of file
diff --git a/examples/basyx.grafana/stop.bat b/examples/basyx.grafana/stop.bat
new file mode 100644
index 0000000..58694d0
--- /dev/null
+++ b/examples/basyx.grafana/stop.bat
@@ -0,0 +1 @@
+docker-compose down
\ No newline at end of file
diff --git a/examples/basyx.grafana/stop.sh b/examples/basyx.grafana/stop.sh
new file mode 100644
index 0000000..f5139e2
--- /dev/null
+++ b/examples/basyx.grafana/stop.sh
@@ -0,0 +1,2 @@
+#!/usr/bin/env sh
+docker-compose down
\ No newline at end of file
diff --git a/examples/basyx.hello_world/.gitignore b/examples/basyx.hello_world/.gitignore
new file mode 100644
index 0000000..02eeb17
--- /dev/null
+++ b/examples/basyx.hello_world/.gitignore
@@ -0,0 +1,69 @@
+.classpath
+.project
+
+regressiontest/
+target/
+pom.xml.tag
+pom.xml.releaseBackup
+pom.xml.versionsBackup
+pom.xml.next
+release.properties
+dependency-reduced-pom.xml
+buildNumber.properties
+.mvn/timing.properties
+.mvn/wrapper/maven-wrapper.jar
+.metadata
+bin/
+tmp/
+*.tmp
+*.bak
+*.swp
+*~.nib
+local.properties
+.settings/
+.loadpath
+.recommenders
+
+# External tool builders
+.externalToolBuilders/
+
+# Locally stored "Eclipse launch configurations"
+*.launch
+
+# PyDev specific (Python IDE for Eclipse)
+*.pydevproject
+
+# CDT-specific (C/C++ Development Tooling)
+.cproject
+
+# CDT- autotools
+.autotools
+
+# Java annotation processor (APT)
+.factorypath
+
+# PDT-specific (PHP Development Tools)
+.buildpath
+
+# sbteclipse plugin
+.target
+
+# Tern plugin
+.tern-project
+
+# TeXlipse plugin
+.texlipse
+
+# STS (Spring Tool Suite)
+.springBeans
+
+# Code Recommenders
+.recommenders/
+
+# Annotation Processing
+.apt_generated/
+
+# Scala IDE specific (Scala & Java development for Eclipse)
+.cache-main
+.scala_dependencies
+.worksheet
\ No newline at end of file
diff --git a/examples/basyx.hello_world/pom.xml b/examples/basyx.hello_world/pom.xml
new file mode 100644
index 0000000..d5aa122
--- /dev/null
+++ b/examples/basyx.hello_world/pom.xml
@@ -0,0 +1,61 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<groupId>org.eclipse.basyx</groupId>
+	<artifactId>basyx.hello_world</artifactId>
+	<version>1.0.0</version>
+	<name>BaSyx Hello World</name>
+	
+		<properties>
+		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+	</properties>
+	
+		<build>
+		<sourceDirectory>src/main/java</sourceDirectory>
+		<testSourceDirectory>src/test/java</testSourceDirectory>
+
+		<plugins>
+			<!-- Compile Sources using Java 8 -->
+			<plugin>
+				<artifactId>maven-compiler-plugin</artifactId>
+				<version>3.8.1</version>
+				<configuration>
+					<source>1.8</source>
+					<target>1.8</target>
+				</configuration>
+			</plugin>
+		</plugins>
+	</build>
+	
+	<dependencies>
+		<!-- Add BaSys components from local repository. This contains the dependency to the basyx.sdk-->
+		<dependency>
+			<groupId>org.eclipse.basyx</groupId>
+			<artifactId>basyx.components.lib</artifactId>
+			<version>1.0.0</version>
+		</dependency>
+		
+		<!-- Add Registry Server component dependency -->
+		<dependency>
+			<groupId>org.eclipse.basyx</groupId>
+			<artifactId>basyx.components.registry</artifactId>
+			<version>1.0.2</version>
+		</dependency>
+				
+		<!-- Add AAS Server component dependency -->
+		<dependency>
+			<groupId>org.eclipse.basyx</groupId>
+			<artifactId>basyx.components.AASServer</artifactId>
+			<version>1.0.0</version>
+		</dependency>
+		
+		
+		<!-- JUnit 4 for running JUnit tests -->
+		<dependency>
+			<groupId>junit</groupId>
+			<artifactId>junit</artifactId>
+			<version>4.12</version>
+		</dependency>
+	</dependencies>
+	
+</project>
\ No newline at end of file
diff --git a/examples/basyx.hello_world/src/main/java/org/eclipse/basyx/hello_world/Client.java b/examples/basyx.hello_world/src/main/java/org/eclipse/basyx/hello_world/Client.java
new file mode 100644
index 0000000..3235f5a
--- /dev/null
+++ b/examples/basyx.hello_world/src/main/java/org/eclipse/basyx/hello_world/Client.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.hello_world;
+
+import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
+import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+
+/**
+ * This class connects to the server created in Server
+ * 
+ * It retrieves the Submodel and prints the
+ * idShort and Value of the contained Property to the console
+ * 
+ * @author schnicke, conradi
+ *
+ */
+public class Client {
+	public static void main(String[] args) {
+		// Create Manager
+		ConnectedAssetAdministrationShellManager manager =
+				new ConnectedAssetAdministrationShellManager(new AASRegistryProxy(Server.REGISTRYPATH));
+
+		// Retrieve submodel
+		ISubmodel submodel = manager.retrieveSubmodel(Server.OVENAASID, Server.DOCUSMID);
+
+		// Retrieve MaxTemp Property
+		ISubmodelElement maxTemp = submodel.getSubmodelElement(Server.MAXTEMPID);
+
+		// Print value
+		System.out.println(maxTemp.getIdShort() + " is " + maxTemp.getValue());
+	}
+}
diff --git a/examples/basyx.hello_world/src/main/java/org/eclipse/basyx/hello_world/Server.java b/examples/basyx.hello_world/src/main/java/org/eclipse/basyx/hello_world/Server.java
new file mode 100644
index 0000000..b2615cc
--- /dev/null
+++ b/examples/basyx.hello_world/src/main/java/org/eclipse/basyx/hello_world/Server.java
@@ -0,0 +1,100 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.hello_world;
+
+import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
+import org.eclipse.basyx.aas.metamodel.api.parts.asset.AssetKind;
+import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.CustomId;
+import org.eclipse.basyx.aas.metamodel.map.parts.Asset;
+import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
+import org.eclipse.basyx.components.aas.AASServerComponent;
+import org.eclipse.basyx.components.aas.configuration.AASServerBackend;
+import org.eclipse.basyx.components.aas.configuration.BaSyxAASServerConfiguration;
+import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
+import org.eclipse.basyx.components.registry.RegistryComponent;
+import org.eclipse.basyx.components.registry.configuration.BaSyxRegistryConfiguration;
+import org.eclipse.basyx.components.registry.configuration.RegistryBackend;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+
+/**
+ * This class starts an AAS server and a Registry server
+ * 
+ * An AAS and a Submodel containing a Property "maxTemp"
+ * is uploaded to the AAS server and registered in the Registry server.
+ * 
+ * @author schnicke, conradi
+ *
+ */
+public class Server {
+	// Server URLs
+	public static final String REGISTRYPATH = "http://localhost:4000/registry";
+	public static final String AASSERVERPATH = "http://localhost:4001/aasServer";
+
+	// AAS/Submodel/Property Ids
+	public static final IIdentifier OVENAASID = new CustomId("eclipse.basyx.aas.oven");
+	public static final IIdentifier DOCUSMID = new CustomId("eclipse.basyx.submodel.documentation");
+	public static final String MAXTEMPID = "maxTemp";
+
+	public static void main(String[] args) {
+		// Create Infrastructure
+		startRegistry();
+		startAASServer();
+
+		// Create Manager - This manager is used to interact with an AAS server
+		ConnectedAssetAdministrationShellManager manager = 
+				new ConnectedAssetAdministrationShellManager(new AASRegistryProxy(REGISTRYPATH));
+		
+		// Create AAS and push it to server
+		Asset asset = new Asset("ovenAsset", new CustomId("eclipse.basyx.asset.oven"), AssetKind.INSTANCE);
+		AssetAdministrationShell shell = new AssetAdministrationShell("oven", OVENAASID, asset);
+		
+		// The manager uploads the AAS and registers it in the Registry server
+		manager.createAAS(shell, AASSERVERPATH);
+		
+		// Create submodel
+		Submodel documentationSubmodel = new Submodel("documentationSm", DOCUSMID);
+
+		// - Create property
+		Property maxTemp = new Property(MAXTEMPID, 1000);
+
+		// Add the property to the Submodel
+		documentationSubmodel.addSubmodelElement(maxTemp);
+
+		// - Push the Submodel to the AAS server
+		manager.createSubmodel(shell.getIdentification(), documentationSubmodel);
+	}
+
+	/**
+	 * Starts an empty registry at "http://localhost:4000"
+	 */
+	private static void startRegistry() {
+		BaSyxContextConfiguration contextConfig = new BaSyxContextConfiguration(4000, "/registry");
+		BaSyxRegistryConfiguration registryConfig = new BaSyxRegistryConfiguration(RegistryBackend.INMEMORY);
+		RegistryComponent registry = new RegistryComponent(contextConfig, registryConfig);
+
+		// Start the created server
+		registry.startComponent();
+	}
+
+	/**
+	 * Startup an empty server at "http://localhost:4001/"
+	 */
+	private static void startAASServer() {
+		BaSyxContextConfiguration contextConfig = new BaSyxContextConfiguration(4001, "/aasServer");
+		BaSyxAASServerConfiguration aasServerConfig = new BaSyxAASServerConfiguration(AASServerBackend.INMEMORY, "", REGISTRYPATH);
+		AASServerComponent aasServer = new AASServerComponent(contextConfig, aasServerConfig);
+
+		// Start the created server
+		aasServer.startComponent();
+	}
+}
diff --git a/examples/basyx.nodered/.gitignore b/examples/basyx.nodered/.gitignore
new file mode 100644
index 0000000..c5294d7
--- /dev/null
+++ b/examples/basyx.nodered/.gitignore
@@ -0,0 +1,3 @@
+/mosquitto/log/mosquitto.log
+/node-red/.flows.json.backup
+/node-red/.flows_cred.json.backup
\ No newline at end of file
diff --git a/examples/basyx.nodered/Dockerfile b/examples/basyx.nodered/Dockerfile
new file mode 100644
index 0000000..4ccce8f
--- /dev/null
+++ b/examples/basyx.nodered/Dockerfile
@@ -0,0 +1,17 @@
+FROM nodered/node-red
+USER root
+
+# Copy package.json to the WORKDIR so npm builds all
+# of your added nodes modules for Node-RED
+COPY package.json .
+COPY ./node-red-contrib-aas-connect ./node-red-contrib-aas-connect
+RUN npm install --unsafe-perm --no-update-notifier --no-fund --only=production --quiet
+RUN npm install ./node-red-contrib-aas-connect
+
+# Copy _your_ Node-RED project files into place
+# NOTE: This will only work if you DO NOT later mount /data as an external volume.
+#       If you need to use an external volume for persistence then
+#       copy your settings and flows files to that volume instead.
+COPY settings.js /data/settings.js
+# COPY flows_cred.json /data/flows_cred.json
+COPY flows.json /data/flows.json
\ No newline at end of file
diff --git a/examples/basyx.nodered/build.bat b/examples/basyx.nodered/build.bat
new file mode 100644
index 0000000..6e3726f
--- /dev/null
+++ b/examples/basyx.nodered/build.bat
@@ -0,0 +1 @@
+docker build -t basyx/node-red:0.1.0-SNAPSHOT .
\ No newline at end of file
diff --git a/examples/basyx.nodered/build.sh b/examples/basyx.nodered/build.sh
new file mode 100644
index 0000000..ce0a3c0
--- /dev/null
+++ b/examples/basyx.nodered/build.sh
@@ -0,0 +1,2 @@
+#!/usr/bin/env sh
+docker build -t basyx/node-red:0.1.0-SNAPSHOT .
\ No newline at end of file
diff --git a/examples/basyx.nodered/docker-compose.yml b/examples/basyx.nodered/docker-compose.yml
new file mode 100644
index 0000000..abf88fc
--- /dev/null
+++ b/examples/basyx.nodered/docker-compose.yml
@@ -0,0 +1,41 @@
+version: '3'
+services:
+
+  registry:
+    image: eclipsebasyx/aas-registry:1.0.1
+    container_name: dashboard-registry
+    ports:
+      - 4000:4000
+
+  dashboard-aas:
+    image: eclipsebasyx/dashboard-aas:0.1.0-SNAPSHOT
+    container_name: dashboard-aas
+    environment:
+      - BaSyxDashboardSubmodel_Min=15
+#      - BaSyxDashboardSubmodel_Max=30
+    ports:
+      - 6400:6400
+
+  aas-wrapper:
+    image: eclipsebasyx/aas-wrapper:0.1.0-SNAPSHOT
+    container_name: aas-wrapper
+    ports:
+      - 6500:6500
+
+  node-red:
+    image: eclipsebasyx/examples-dataflow-nodered:0.1.0-SNAPSHOT
+    container_name: node-red
+    ports:
+      - 1880:1880
+    volumes:
+      - ./node-red:/data
+
+  mosquitto:
+    image: eclipse-mosquitto:latest
+    container_name: mosquitto
+    ports:
+      - 1883:1883
+      - 9001:9001
+    volumes:
+      - ./mosquitto/config:/mosquitto/config
+      - ./mosquitto/log:/mosquitto/log
\ No newline at end of file
diff --git a/examples/basyx.nodered/flows.json b/examples/basyx.nodered/flows.json
new file mode 100644
index 0000000..0e22486
--- /dev/null
+++ b/examples/basyx.nodered/flows.json
@@ -0,0 +1 @@
+[{"id":"ac89e902.a48598","type":"tab","label":"AAS Temperature","disabled":false,"info":""},{"id":"91383a96.5b2e48","type":"tab","label":"Test","disabled":false,"info":""},{"id":"1b4daff8.52358","type":"mqtt-broker","z":"","name":"Streamsheets Mosquitto","broker":"http://streamsheets","port":"1883","clientid":"","usetls":false,"compatmode":false,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""},{"id":"2289cf21.0a21b","type":"inject","z":"ac89e902.a48598","name":"Start","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":110,"y":120,"wires":[["c3659321.46995"]]},{"id":"c3659321.46995","type":"get-aas-property","z":"ac89e902.a48598","name":"Get Temperature","property":"temp","period":1,"x":270,"y":120,"wires":[["a56bd8e1.1777c8","2c13d59c.208cea","8c41e115.ac913"]]},{"id":"4e72f0db.c2a7a","type":"inject","z":"91383a96.5b2e48","name":"Data","props":[{"p":"values","v":"[22.344,23.434,24.342,21.098]","vt":"json"},{"p":"timestamp","v":"[121323,2112231,321331,321321]","vt":"json"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":140,"y":100,"wires":[["a53d7930.6109f8","4a734a5f.b22314","ab2d648a.1767f8"]]},{"id":"a53d7930.6109f8","type":"debug","z":"91383a96.5b2e48","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":250,"y":240,"wires":[]},{"id":"4a734a5f.b22314","type":"function","z":"91383a96.5b2e48","name":"Calculate Average","func":"msg.avg = msg.values.reduce((a,b) => a + b, 0) / msg.values.length;\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":450,"y":120,"wires":[["6b28c27b.5547bc"]]},{"id":"6b28c27b.5547bc","type":"debug","z":"91383a96.5b2e48","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":710,"y":120,"wires":[]},{"id":"ab2d648a.1767f8","type":"function","z":"91383a96.5b2e48","name":"Calculate Fahrenheit","func":"msg.fahrenheit = msg.values.map(v => v * 1.8 + 32);\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":460,"y":180,"wires":[["5e614070.a223f"]]},{"id":"5e614070.a223f","type":"debug","z":"91383a96.5b2e48","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":710,"y":180,"wires":[]},{"id":"e733d05.63a9c3","type":"iot-datasource","z":"ac89e902.a48598","name":"Temperature Datasource","tstampField":"tstamp","dataField":"data","disableDiscover":false,"x":730,"y":240,"wires":[[]]},{"id":"8e627da8.65b74","type":"mqtt out","z":"ac89e902.a48598","name":"MQTT Avg Temp Publisher","topic":"temperature/average","qos":"","retain":"","broker":"1b4daff8.52358","x":740,"y":120,"wires":[]},{"id":"7aa9e937.6575c8","type":"mqtt in","z":"ac89e902.a48598","name":"MQTT Avg Temp Consumer","topic":"temperature/average","qos":"2","datatype":"json","broker":"1b4daff8.52358","x":160,"y":360,"wires":[["f96c72b.3be659"]]},{"id":"f96c72b.3be659","type":"debug","z":"ac89e902.a48598","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload.average","targetType":"msg","statusVal":"","statusType":"auto","x":420,"y":360,"wires":[]},{"id":"a56bd8e1.1777c8","type":"function","z":"ac89e902.a48598","name":"Calculate Average","func":"const payload = msg.payload;\nlet average = payload.data.reduce((a,b) => a + b, 0) / payload.data.length;\npayload.average = average;\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":490,"y":120,"wires":[["8e627da8.65b74"]]},{"id":"2c13d59c.208cea","type":"function","z":"ac89e902.a48598","name":"Calculate Fahrenheit","func":"const payload = msg.payload;\nlet fahrenheit = payload.data.map(v => v * 1.8 + 32);\npayload.fahrenheit = fahrenheit;\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":500,"y":180,"wires":[["a3733cf8.97468"]]},{"id":"a3733cf8.97468","type":"mqtt out","z":"ac89e902.a48598","name":"MQTT Fahrenheit Temp Publisher","topic":"temperature/fahrenheit","qos":"","retain":"","broker":"1b4daff8.52358","x":760,"y":180,"wires":[]},{"id":"8c41e115.ac913","type":"function","z":"ac89e902.a48598","name":"Get most recent","func":"msg.payload.tstamp = new Date(msg.payload.tstamp.pop()).getTime();\nmsg.payload.data = msg.payload.data.pop();\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":480,"y":240,"wires":[["e733d05.63a9c3"]]}]
\ No newline at end of file
diff --git a/examples/basyx.nodered/mosquitto/config/mosquitto.conf b/examples/basyx.nodered/mosquitto/config/mosquitto.conf
new file mode 100644
index 0000000..9bf5429
--- /dev/null
+++ b/examples/basyx.nodered/mosquitto/config/mosquitto.conf
@@ -0,0 +1,988 @@
+# Config file for mosquitto
+#
+# See mosquitto.conf(5) for more information.
+#
+# Default values are shown, uncomment to change.
+#
+# Use the # character to indicate a comment, but only if it is the
+# very first character on the line.
+
+# =================================================================
+# General configuration
+# =================================================================
+
+# Use per listener security settings.
+#
+# It is recommended this option be set before any other options.
+#
+# If this option is set to true, then all authentication and access control
+# options are controlled on a per listener basis. The following options are
+# affected:
+#
+# password_file acl_file psk_file auth_plugin auth_opt_* allow_anonymous
+# auto_id_prefix allow_zero_length_clientid
+#
+# Note that if set to true, then a durable client (i.e. with clean session set
+# to false) that has disconnected will use the ACL settings defined for the
+# listener that it was most recently connected to.
+#
+# The default behaviour is for this to be set to false, which maintains the
+# setting behaviour from previous versions of mosquitto.
+#per_listener_settings false
+
+
+# If a client is subscribed to multiple subscriptions that overlap, e.g. foo/#
+# and foo/+/baz , then MQTT expects that when the broker receives a message on
+# a topic that matches both subscriptions, such as foo/bar/baz, then the client
+# should only receive the message once.
+# Mosquitto keeps track of which clients a message has been sent to in order to
+# meet this requirement. The allow_duplicate_messages option allows this
+# behaviour to be disabled, which may be useful if you have a large number of
+# clients subscribed to the same set of topics and are very concerned about
+# minimising memory usage.
+# It can be safely set to true if you know in advance that your clients will
+# never have overlapping subscriptions, otherwise your clients must be able to
+# correctly deal with duplicate messages even when then have QoS=2.
+#allow_duplicate_messages false
+
+# This option controls whether a client is allowed to connect with a zero
+# length client id or not. This option only affects clients using MQTT v3.1.1
+# and later. If set to false, clients connecting with a zero length client id
+# are disconnected. If set to true, clients will be allocated a client id by
+# the broker. This means it is only useful for clients with clean session set
+# to true.
+#allow_zero_length_clientid true
+
+# If allow_zero_length_clientid is true, this option allows you to set a prefix
+# to automatically generated client ids to aid visibility in logs.
+# Defaults to 'auto-'
+#auto_id_prefix auto-
+
+# This option affects the scenario when a client subscribes to a topic that has
+# retained messages. It is possible that the client that published the retained
+# message to the topic had access at the time they published, but that access
+# has been subsequently removed. If check_retain_source is set to true, the
+# default, the source of a retained message will be checked for access rights
+# before it is republished. When set to false, no check will be made and the
+# retained message will always be published. This affects all listeners.
+#check_retain_source true
+
+# QoS 1 and 2 messages will be allowed inflight per client until this limit
+# is exceeded.  Defaults to 0. (No maximum)
+# See also max_inflight_messages
+#max_inflight_bytes 0
+
+# The maximum number of QoS 1 and 2 messages currently inflight per
+# client.
+# This includes messages that are partway through handshakes and
+# those that are being retried. Defaults to 20. Set to 0 for no
+# maximum. Setting to 1 will guarantee in-order delivery of QoS 1
+# and 2 messages.
+#max_inflight_messages 20
+
+# For MQTT v5 clients, it is possible to have the server send a "server
+# keepalive" value that will override the keepalive value set by the client.
+# This is intended to be used as a mechanism to say that the server will
+# disconnect the client earlier than it anticipated, and that the client should
+# use the new keepalive value. The max_keepalive option allows you to specify
+# that clients may only connect with keepalive less than or equal to this
+# value, otherwise they will be sent a server keepalive telling them to use
+# max_keepalive. This only applies to MQTT v5 clients. The maximum value
+# allowable is 65535. Do not set below 10.
+#max_keepalive 65535
+
+# For MQTT v5 clients, it is possible to have the server send a "maximum packet
+# size" value that will instruct the client it will not accept MQTT packets
+# with size greater than max_packet_size bytes. This applies to the full MQTT
+# packet, not just the payload. Setting this option to a positive value will
+# set the maximum packet size to that number of bytes. If a client sends a
+# packet which is larger than this value, it will be disconnected. This applies
+# to all clients regardless of the protocol version they are using, but v3.1.1
+# and earlier clients will of course not have received the maximum packet size
+# information. Defaults to no limit. Setting below 20 bytes is forbidden
+# because it is likely to interfere with ordinary client operation, even with
+# very small payloads.
+#max_packet_size 0
+
+# QoS 1 and 2 messages above those currently in-flight will be queued per
+# client until this limit is exceeded.  Defaults to 0. (No maximum)
+# See also max_queued_messages.
+# If both max_queued_messages and max_queued_bytes are specified, packets will
+# be queued until the first limit is reached.
+#max_queued_bytes 0
+
+# The maximum number of QoS 1 and 2 messages to hold in a queue per client
+# above those that are currently in-flight.  Defaults to 100. Set
+# to 0 for no maximum (not recommended).
+# See also queue_qos0_messages.
+# See also max_queued_bytes.
+#max_queued_messages 100
+#
+# This option sets the maximum number of heap memory bytes that the broker will
+# allocate, and hence sets a hard limit on memory use by the broker.  Memory
+# requests that exceed this value will be denied. The effect will vary
+# depending on what has been denied. If an incoming message is being processed,
+# then the message will be dropped and the publishing client will be
+# disconnected. If an outgoing message is being sent, then the individual
+# message will be dropped and the receiving client will be disconnected.
+# Defaults to no limit.
+#memory_limit 0
+
+# This option sets the maximum publish payload size that the broker will allow.
+# Received messages that exceed this size will not be accepted by the broker.
+# The default value is 0, which means that all valid MQTT messages are
+# accepted. MQTT imposes a maximum payload size of 268435455 bytes.
+#message_size_limit 0
+
+# This option allows persistent clients (those with clean session set to false)
+# to be removed if they do not reconnect within a certain time frame.
+#
+# This is a non-standard option in MQTT V3.1 but allowed in MQTT v3.1.1.
+#
+# Badly designed clients may set clean session to false whilst using a randomly
+# generated client id. This leads to persistent clients that will never
+# reconnect. This option allows these clients to be removed.
+#
+# The expiration period should be an integer followed by one of h d w m y for
+# hour, day, week, month and year respectively. For example
+#
+# persistent_client_expiration 2m
+# persistent_client_expiration 14d
+# persistent_client_expiration 1y
+#
+# The default if not set is to never expire persistent clients.
+#persistent_client_expiration
+
+# Write process id to a file. Default is a blank string which means
+# a pid file shouldn't be written.
+# This should be set to /var/run/mosquitto.pid if mosquitto is
+# being run automatically on boot with an init script and
+# start-stop-daemon or similar.
+#pid_file
+
+# Set to true to queue messages with QoS 0 when a persistent client is
+# disconnected. These messages are included in the limit imposed by
+# max_queued_messages and max_queued_bytes
+# Defaults to false.
+# This is a non-standard option for the MQTT v3.1 spec but is allowed in
+# v3.1.1.
+#queue_qos0_messages false
+
+# Set to false to disable retained message support. If a client publishes a
+# message with the retain bit set, it will be disconnected if this is set to
+# false.
+#retain_available true
+
+# Disable Nagle's algorithm on client sockets. This has the effect of reducing
+# latency of individual messages at the potential cost of increasing the number
+# of packets being sent.
+#set_tcp_nodelay false
+
+# Time in seconds between updates of the $SYS tree.
+# Set to 0 to disable the publishing of the $SYS tree.
+#sys_interval 10
+
+# The MQTT specification requires that the QoS of a message delivered to a
+# subscriber is never upgraded to match the QoS of the subscription. Enabling
+# this option changes this behaviour. If upgrade_outgoing_qos is set true,
+# messages sent to a subscriber will always match the QoS of its subscription.
+# This is a non-standard option explicitly disallowed by the spec.
+#upgrade_outgoing_qos false
+
+# When run as root, drop privileges to this user and its primary
+# group.
+# Set to root to stay as root, but this is not recommended.
+# If run as a non-root user, this setting has no effect.
+# Note that on Windows this has no effect and so mosquitto should
+# be started by the user you wish it to run as.
+#user mosquitto
+
+# =================================================================
+# Default listener
+# =================================================================
+
+# IP address/hostname to bind the default listener to. If not
+# given, the default listener will not be bound to a specific
+# address and so will be accessible to all network interfaces.
+# bind_address ip-address/host name
+#bind_address
+
+# Port to use for the default listener.
+#port 1883
+
+# Bind the listener to a specific interface. This is similar to
+# bind_address above but is useful when an interface has multiple addresses or
+# the address may change. It is valid to use this with the bind_address option,
+# but take care that the interface you are binding to contains the address you
+# are binding to, otherwise you will not be able to connect.
+# Example: bind_interface eth0
+#bind_interface
+
+# When a listener is using the websockets protocol, it is possible to serve
+# http data as well. Set http_dir to a directory which contains the files you
+# wish to serve. If this option is not specified, then no normal http
+# connections will be possible.
+#http_dir
+
+# The maximum number of client connections to allow. This is
+# a per listener setting.
+# Default is -1, which means unlimited connections.
+# Note that other process limits mean that unlimited connections
+# are not really possible. Typically the default maximum number of
+# connections possible is around 1024.
+#max_connections -1
+
+# Choose the protocol to use when listening.
+# This can be either mqtt or websockets.
+# Websockets support is currently disabled by default at compile time.
+# Certificate based TLS may be used with websockets, except that
+# only the cafile, certfile, keyfile and ciphers options are supported.
+#protocol mqtt
+
+# Set use_username_as_clientid to true to replace the clientid that a client
+# connected with with its username. This allows authentication to be tied to
+# the clientid, which means that it is possible to prevent one client
+# disconnecting another by using the same clientid.
+# If a client connects with no username it will be disconnected as not
+# authorised when this option is set to true.
+# Do not use in conjunction with clientid_prefixes.
+# See also use_identity_as_username.
+#use_username_as_clientid
+
+# -----------------------------------------------------------------
+# Certificate based SSL/TLS support
+# -----------------------------------------------------------------
+# The following options can be used to enable SSL/TLS support for
+# this listener. Note that the recommended port for MQTT over TLS
+# is 8883, but this must be set manually.
+#
+# See also the mosquitto-tls man page.
+
+# At least one of cafile or capath must be defined. They both
+# define methods of accessing the PEM encoded Certificate
+# Authority certificates that have signed your server certificate
+# and that you wish to trust.
+# cafile defines the path to a file containing the CA certificates.
+# capath defines a directory that will be searched for files
+# containing the CA certificates. For capath to work correctly, the
+# certificate files must have ".crt" as the file ending and you must run
+# "openssl rehash <path to capath>" each time you add/remove a certificate.
+#cafile
+#capath
+
+# Path to the PEM encoded server certificate.
+#certfile
+
+# Path to the PEM encoded keyfile.
+#keyfile
+
+
+# If you have require_certificate set to true, you can create a certificate
+# revocation list file to revoke access to particular client certificates. If
+# you have done this, use crlfile to point to the PEM encoded revocation file.
+#crlfile
+
+# If you wish to control which encryption ciphers are used, use the ciphers
+# option. The list of available ciphers can be obtained using the "openssl
+# ciphers" command and should be provided in the same format as the output of
+# that command.
+# If unset defaults to DEFAULT:!aNULL:!eNULL:!LOW:!EXPORT:!SSLv2:@STRENGTH
+#ciphers DEFAULT:!aNULL:!eNULL:!LOW:!EXPORT:!SSLv2:@STRENGTH
+
+# To allow the use of ephemeral DH key exchange, which provides forward
+# security, the listener must load DH parameters. This can be specified with
+# the dhparamfile option. The dhparamfile can be generated with the command
+# e.g. "openssl dhparam -out dhparam.pem 2048"
+#dhparamfile
+
+# By default a TLS enabled listener will operate in a similar fashion to a
+# https enabled web server, in that the server has a certificate signed by a CA
+# and the client will verify that it is a trusted certificate. The overall aim
+# is encryption of the network traffic. By setting require_certificate to true,
+# the client must provide a valid certificate in order for the network
+# connection to proceed. This allows access to the broker to be controlled
+# outside of the mechanisms provided by MQTT.
+#require_certificate false
+
+# This option defines the version of the TLS protocol to use for this listener.
+# The default value allows all of v1.3, v1.2 and v1.1. The valid values are
+# tlsv1.3 tlsv1.2 and tlsv1.1.
+#tls_version
+
+# If require_certificate is true, you may set use_identity_as_username to true
+# to use the CN value from the client certificate as a username. If this is
+# true, the password_file option will not be used for this listener.
+# This takes priority over use_subject_as_username.
+# See also use_subject_as_username.
+#use_identity_as_username false
+
+# If require_certificate is true, you may set use_subject_as_username to true
+# to use the complete subject value from the client certificate as a username.
+# If this is true, the password_file option will not be used for this listener.
+# See also use_identity_as_username
+#use_subject_as_username false
+
+# -----------------------------------------------------------------
+# Pre-shared-key based SSL/TLS support
+# -----------------------------------------------------------------
+# The following options can be used to enable PSK based SSL/TLS support for
+# this listener. Note that the recommended port for MQTT over TLS is 8883, but
+# this must be set manually.
+#
+# See also the mosquitto-tls man page and the "Certificate based SSL/TLS
+# support" section. Only one of certificate or PSK encryption support can be
+# enabled for any listener.
+
+# The psk_hint option enables pre-shared-key support for this listener and also
+# acts as an identifier for this listener. The hint is sent to clients and may
+# be used locally to aid authentication. The hint is a free form string that
+# doesn't have much meaning in itself, so feel free to be creative.
+# If this option is provided, see psk_file to define the pre-shared keys to be
+# used or create a security plugin to handle them.
+#psk_hint
+
+# When using PSK, the encryption ciphers used will be chosen from the list of
+# available PSK ciphers. If you want to control which ciphers are available,
+# use the "ciphers" option.  The list of available ciphers can be obtained
+# using the "openssl ciphers" command and should be provided in the same format
+# as the output of that command.
+#ciphers
+
+# Set use_identity_as_username to have the psk identity sent by the client used
+# as its username. Authentication will be carried out using the PSK rather than
+# the MQTT username/password and so password_file will not be used for this
+# listener.
+#use_identity_as_username false
+
+
+# =================================================================
+# Extra listeners
+# =================================================================
+
+# Listen on a port/ip address combination. By using this variable
+# multiple times, mosquitto can listen on more than one port. If
+# this variable is used and neither bind_address nor port given,
+# then the default listener will not be started.
+# The port number to listen on must be given. Optionally, an ip
+# address or host name may be supplied as a second argument. In
+# this case, mosquitto will attempt to bind the listener to that
+# address and so restrict access to the associated network and
+# interface. By default, mosquitto will listen on all interfaces.
+# Note that for a websockets listener it is not possible to bind to a host
+# name.
+# listener port-number [ip address/host name]
+#listener
+
+# Bind the listener to a specific interface. This is similar to
+# the [ip address/host name] part of the listener definition, but is useful
+# when an interface has multiple addresses or the address may change. It is
+# valid to use this with the [ip address/host name] part of the listener
+# definition, but take care that the interface you are binding to contains the
+# address you are binding to, otherwise you will not be able to connect.
+# Only available on Linux and requires elevated privileges.
+#
+# Example: bind_interface eth0
+#bind_interface
+
+# When a listener is using the websockets protocol, it is possible to serve
+# http data as well. Set http_dir to a directory which contains the files you
+# wish to serve. If this option is not specified, then no normal http
+# connections will be possible.
+#http_dir
+
+# The maximum number of client connections to allow. This is
+# a per listener setting.
+# Default is -1, which means unlimited connections.
+# Note that other process limits mean that unlimited connections
+# are not really possible. Typically the default maximum number of
+# connections possible is around 1024.
+#max_connections -1
+
+# The listener can be restricted to operating within a topic hierarchy using
+# the mount_point option. This is achieved be prefixing the mount_point string
+# to all topics for any clients connected to this listener. This prefixing only
+# happens internally to the broker; the client will not see the prefix.
+#mount_point
+
+# Choose the protocol to use when listening.
+# This can be either mqtt or websockets.
+# Certificate based TLS may be used with websockets, except that only the
+# cafile, certfile, keyfile and ciphers options are supported.
+#protocol mqtt
+
+# Set use_username_as_clientid to true to replace the clientid that a client
+# connected with with its username. This allows authentication to be tied to
+# the clientid, which means that it is possible to prevent one client
+# disconnecting another by using the same clientid.
+# If a client connects with no username it will be disconnected as not
+# authorised when this option is set to true.
+# Do not use in conjunction with clientid_prefixes.
+# See also use_identity_as_username.
+#use_username_as_clientid
+
+# Change the websockets headers size. This is a global option, it is not
+# possible to set per listener. This option sets the size of the buffer used in
+# the libwebsockets library when reading HTTP headers. If you are passing large
+# header data such as cookies then you may need to increase this value. If left
+# unset, or set to 0, then the default of 1024 bytes will be used.
+#websockets_headers_size
+
+# -----------------------------------------------------------------
+# Certificate based SSL/TLS support
+# -----------------------------------------------------------------
+# The following options can be used to enable certificate based SSL/TLS support
+# for this listener. Note that the recommended port for MQTT over TLS is 8883,
+# but this must be set manually.
+#
+# See also the mosquitto-tls man page and the "Pre-shared-key based SSL/TLS
+# support" section. Only one of certificate or PSK encryption support can be
+# enabled for any listener.
+
+# At least one of cafile or capath must be defined to enable certificate based
+# TLS encryption. They both define methods of accessing the PEM encoded
+# Certificate Authority certificates that have signed your server certificate
+# and that you wish to trust.
+# cafile defines the path to a file containing the CA certificates.
+# capath defines a directory that will be searched for files
+# containing the CA certificates. For capath to work correctly, the
+# certificate files must have ".crt" as the file ending and you must run
+# "openssl rehash <path to capath>" each time you add/remove a certificate.
+#cafile
+#capath
+
+# Path to the PEM encoded server certificate.
+#certfile
+
+# Path to the PEM encoded keyfile.
+#keyfile
+
+
+# If you wish to control which encryption ciphers are used, use the ciphers
+# option. The list of available ciphers can be optained using the "openssl
+# ciphers" command and should be provided in the same format as the output of
+# that command.
+#ciphers
+
+# If you have require_certificate set to true, you can create a certificate
+# revocation list file to revoke access to particular client certificates. If
+# you have done this, use crlfile to point to the PEM encoded revocation file.
+#crlfile
+
+# To allow the use of ephemeral DH key exchange, which provides forward
+# security, the listener must load DH parameters. This can be specified with
+# the dhparamfile option. The dhparamfile can be generated with the command
+# e.g. "openssl dhparam -out dhparam.pem 2048"
+#dhparamfile
+
+# By default an TLS enabled listener will operate in a similar fashion to a
+# https enabled web server, in that the server has a certificate signed by a CA
+# and the client will verify that it is a trusted certificate. The overall aim
+# is encryption of the network traffic. By setting require_certificate to true,
+# the client must provide a valid certificate in order for the network
+# connection to proceed. This allows access to the broker to be controlled
+# outside of the mechanisms provided by MQTT.
+#require_certificate false
+
+# If require_certificate is true, you may set use_identity_as_username to true
+# to use the CN value from the client certificate as a username. If this is
+# true, the password_file option will not be used for this listener.
+#use_identity_as_username false
+
+# -----------------------------------------------------------------
+# Pre-shared-key based SSL/TLS support
+# -----------------------------------------------------------------
+# The following options can be used to enable PSK based SSL/TLS support for
+# this listener. Note that the recommended port for MQTT over TLS is 8883, but
+# this must be set manually.
+#
+# See also the mosquitto-tls man page and the "Certificate based SSL/TLS
+# support" section. Only one of certificate or PSK encryption support can be
+# enabled for any listener.
+
+# The psk_hint option enables pre-shared-key support for this listener and also
+# acts as an identifier for this listener. The hint is sent to clients and may
+# be used locally to aid authentication. The hint is a free form string that
+# doesn't have much meaning in itself, so feel free to be creative.
+# If this option is provided, see psk_file to define the pre-shared keys to be
+# used or create a security plugin to handle them.
+#psk_hint
+
+# When using PSK, the encryption ciphers used will be chosen from the list of
+# available PSK ciphers. If you want to control which ciphers are available,
+# use the "ciphers" option.  The list of available ciphers can be optained
+# using the "openssl ciphers" command and should be provided in the same format
+# as the output of that command.
+#ciphers
+
+# Set use_identity_as_username to have the psk identity sent by the client used
+# as its username. Authentication will be carried out using the PSK rather than
+# the MQTT username/password and so password_file will not be used for this
+# listener.
+#use_identity_as_username false
+
+
+# =================================================================
+# Persistence
+# =================================================================
+
+# If persistence is enabled, save the in-memory database to disk
+# every autosave_interval seconds. If set to 0, the persistence
+# database will only be written when mosquitto exits. See also
+# autosave_on_changes.
+# Note that writing of the persistence database can be forced by
+# sending mosquitto a SIGUSR1 signal.
+#autosave_interval 1800
+
+# If true, mosquitto will count the number of subscription changes, retained
+# messages received and queued messages and if the total exceeds
+# autosave_interval then the in-memory database will be saved to disk.
+# If false, mosquitto will save the in-memory database to disk by treating
+# autosave_interval as a time in seconds.
+#autosave_on_changes false
+
+# Save persistent message data to disk (true/false).
+# This saves information about all messages, including
+# subscriptions, currently in-flight messages and retained
+# messages.
+# retained_persistence is a synonym for this option.
+#persistence false
+
+# The filename to use for the persistent database, not including
+# the path.
+#persistence_file mosquitto.db
+
+# Location for persistent database. Must include trailing /
+# Default is an empty string (current directory).
+# Set to e.g. /var/lib/mosquitto/ if running as a proper service on Linux or
+# similar.
+#persistence_location
+
+
+# =================================================================
+# Logging
+# =================================================================
+
+# Places to log to. Use multiple log_dest lines for multiple
+# logging destinations.
+# Possible destinations are: stdout stderr syslog topic file
+#
+# stdout and stderr log to the console on the named output.
+#
+# syslog uses the userspace syslog facility which usually ends up
+# in /var/log/messages or similar.
+#
+# topic logs to the broker topic '$SYS/broker/log/<severity>',
+# where severity is one of D, E, W, N, I, M which are debug, error,
+# warning, notice, information and message. Message type severity is used by
+# the subscribe/unsubscribe log_types and publishes log messages to
+# $SYS/broker/log/M/susbcribe or $SYS/broker/log/M/unsubscribe.
+#
+# The file destination requires an additional parameter which is the file to be
+# logged to, e.g. "log_dest file /var/log/mosquitto.log". The file will be
+# closed and reopened when the broker receives a HUP signal. Only a single file
+# destination may be configured.
+#
+# Note that if the broker is running as a Windows service it will default to
+# "log_dest none" and neither stdout nor stderr logging is available.
+# Use "log_dest none" if you wish to disable logging.
+log_dest file /mosquitto/log/mosquitto.log
+
+# Types of messages to log. Use multiple log_type lines for logging
+# multiple types of messages.
+# Possible types are: debug, error, warning, notice, information,
+# none, subscribe, unsubscribe, websockets, all.
+# Note that debug type messages are for decoding the incoming/outgoing
+# network packets. They are not logged in "topics".
+#log_type error
+#log_type warning
+#log_type notice
+#log_type information
+
+
+# If set to true, client connection and disconnection messages will be included
+# in the log.
+#connection_messages true
+
+# If using syslog logging (not on Windows), messages will be logged to the
+# "daemon" facility by default. Use the log_facility option to choose which of
+# local0 to local7 to log to instead. The option value should be an integer
+# value, e.g. "log_facility 5" to use local5.
+#log_facility
+
+# If set to true, add a timestamp value to each log message.
+#log_timestamp true
+
+# Set the format of the log timestamp. If left unset, this is the number of
+# seconds since the Unix epoch.
+# This is a free text string which will be passed to the strftime function. To
+# get an ISO 8601 datetime, for example:
+# log_timestamp_format %Y-%m-%dT%H:%M:%S
+#log_timestamp_format
+
+# Change the websockets logging level. This is a global option, it is not
+# possible to set per listener. This is an integer that is interpreted by
+# libwebsockets as a bit mask for its lws_log_levels enum. See the
+# libwebsockets documentation for more details. "log_type websockets" must also
+# be enabled.
+#websockets_log_level 0
+
+
+# =================================================================
+# Security
+# =================================================================
+
+# If set, only clients that have a matching prefix on their
+# clientid will be allowed to connect to the broker. By default,
+# all clients may connect.
+# For example, setting "secure-" here would mean a client "secure-
+# client" could connect but another with clientid "mqtt" couldn't.
+#clientid_prefixes
+
+# Boolean value that determines whether clients that connect
+# without providing a username are allowed to connect. If set to
+# false then a password file should be created (see the
+# password_file option) to control authenticated client access.
+#
+# Defaults to true if no other security options are set. If `password_file` or
+# `psk_file` is set, or if an authentication plugin is loaded which implements
+# username/password or TLS-PSK checks, then `allow_anonymous` defaults to
+# false.
+#
+#allow_anonymous true
+
+# -----------------------------------------------------------------
+# Default authentication and topic access control
+# -----------------------------------------------------------------
+
+# Control access to the broker using a password file. This file can be
+# generated using the mosquitto_passwd utility. If TLS support is not compiled
+# into mosquitto (it is recommended that TLS support should be included) then
+# plain text passwords are used, in which case the file should be a text file
+# with lines in the format:
+# username:password
+# The password (and colon) may be omitted if desired, although this
+# offers very little in the way of security.
+#
+# See the TLS client require_certificate and use_identity_as_username options
+# for alternative authentication options. If an auth_plugin is used as well as
+# password_file, the auth_plugin check will be made first.
+#password_file
+
+# Access may also be controlled using a pre-shared-key file. This requires
+# TLS-PSK support and a listener configured to use it. The file should be text
+# lines in the format:
+# identity:key
+# The key should be in hexadecimal format without a leading "0x".
+# If an auth_plugin is used as well, the auth_plugin check will be made first.
+#psk_file
+
+# Control access to topics on the broker using an access control list
+# file. If this parameter is defined then only the topics listed will
+# have access.
+# If the first character of a line of the ACL file is a # it is treated as a
+# comment.
+# Topic access is added with lines of the format:
+#
+# topic [read|write|readwrite] <topic>
+#
+# The access type is controlled using "read", "write" or "readwrite". This
+# parameter is optional (unless <topic> contains a space character) - if not
+# given then the access is read/write.  <topic> can contain the + or #
+# wildcards as in subscriptions.
+#
+# The first set of topics are applied to anonymous clients, assuming
+# allow_anonymous is true. User specific topic ACLs are added after a
+# user line as follows:
+#
+# user <username>
+#
+# The username referred to here is the same as in password_file. It is
+# not the clientid.
+#
+#
+# If is also possible to define ACLs based on pattern substitution within the
+# topic. The patterns available for substition are:
+#
+# %c to match the client id of the client
+# %u to match the username of the client
+#
+# The substitution pattern must be the only text for that level of hierarchy.
+#
+# The form is the same as for the topic keyword, but using pattern as the
+# keyword.
+# Pattern ACLs apply to all users even if the "user" keyword has previously
+# been given.
+#
+# If using bridges with usernames and ACLs, connection messages can be allowed
+# with the following pattern:
+# pattern write $SYS/broker/connection/%c/state
+#
+# pattern [read|write|readwrite] <topic>
+#
+# Example:
+#
+# pattern write sensor/%u/data
+#
+# If an auth_plugin is used as well as acl_file, the auth_plugin check will be
+# made first.
+#acl_file
+
+# -----------------------------------------------------------------
+# External authentication and topic access plugin options
+# -----------------------------------------------------------------
+
+# External authentication and access control can be supported with the
+# auth_plugin option. This is a path to a loadable plugin. See also the
+# auth_opt_* options described below.
+#
+# The auth_plugin option can be specified multiple times to load multiple
+# plugins. The plugins will be processed in the order that they are specified
+# here. If the auth_plugin option is specified alongside either of
+# password_file or acl_file then the plugin checks will be made first.
+#
+#auth_plugin
+
+# If the auth_plugin option above is used, define options to pass to the
+# plugin here as described by the plugin instructions. All options named
+# using the format auth_opt_* will be passed to the plugin, for example:
+#
+# auth_opt_db_host
+# auth_opt_db_port
+# auth_opt_db_username
+# auth_opt_db_password
+
+
+# =================================================================
+# Bridges
+# =================================================================
+
+# A bridge is a way of connecting multiple MQTT brokers together.
+# Create a new bridge using the "connection" option as described below. Set
+# options for the bridges using the remaining parameters. You must specify the
+# address and at least one topic to subscribe to.
+#
+# Each connection must have a unique name.
+#
+# The address line may have multiple host address and ports specified. See
+# below in the round_robin description for more details on bridge behaviour if
+# multiple addresses are used. Note that if you use an IPv6 address, then you
+# are required to specify a port.
+#
+# The direction that the topic will be shared can be chosen by
+# specifying out, in or both, where the default value is out.
+# The QoS level of the bridged communication can be specified with the next
+# topic option. The default QoS level is 0, to change the QoS the topic
+# direction must also be given.
+#
+# The local and remote prefix options allow a topic to be remapped when it is
+# bridged to/from the remote broker. This provides the ability to place a topic
+# tree in an appropriate location.
+#
+# For more details see the mosquitto.conf man page.
+#
+# Multiple topics can be specified per connection, but be careful
+# not to create any loops.
+#
+# If you are using bridges with cleansession set to false (the default), then
+# you may get unexpected behaviour from incoming topics if you change what
+# topics you are subscribing to. This is because the remote broker keeps the
+# subscription for the old topic. If you have this problem, connect your bridge
+# with cleansession set to true, then reconnect with cleansession set to false
+# as normal.
+#connection <name>
+#address <host>[:<port>] [<host>[:<port>]]
+#topic <topic> [[[out | in | both] qos-level] local-prefix remote-prefix]
+
+
+# If a bridge has topics that have "out" direction, the default behaviour is to
+# send an unsubscribe request to the remote broker on that topic. This means
+# that changing a topic direction from "in" to "out" will not keep receiving
+# incoming messages. Sending these unsubscribe requests is not always
+# desirable, setting bridge_attempt_unsubscribe to false will disable sending
+# the unsubscribe request.
+#bridge_attempt_unsubscribe true
+
+# Set the version of the MQTT protocol to use with for this bridge. Can be one
+# of mqttv311 or mqttv11. Defaults to mqttv311.
+#bridge_protocol_version mqttv311
+
+# Set the clean session variable for this bridge.
+# When set to true, when the bridge disconnects for any reason, all
+# messages and subscriptions will be cleaned up on the remote
+# broker. Note that with cleansession set to true, there may be a
+# significant amount of retained messages sent when the bridge
+# reconnects after losing its connection.
+# When set to false, the subscriptions and messages are kept on the
+# remote broker, and delivered when the bridge reconnects.
+#cleansession false
+
+# Set the amount of time a bridge using the lazy start type must be idle before
+# it will be stopped. Defaults to 60 seconds.
+#idle_timeout 60
+
+# Set the keepalive interval for this bridge connection, in
+# seconds.
+#keepalive_interval 60
+
+# Set the clientid to use on the local broker. If not defined, this defaults to
+# 'local.<clientid>'. If you are bridging a broker to itself, it is important
+# that local_clientid and clientid do not match.
+#local_clientid
+
+# If set to true, publish notification messages to the local and remote brokers
+# giving information about the state of the bridge connection. Retained
+# messages are published to the topic $SYS/broker/connection/<clientid>/state
+# unless the notification_topic option is used.
+# If the message is 1 then the connection is active, or 0 if the connection has
+# failed.
+# This uses the last will and testament feature.
+#notifications true
+
+# Choose the topic on which notification messages for this bridge are
+# published. If not set, messages are published on the topic
+# $SYS/broker/connection/<clientid>/state
+#notification_topic
+
+# Set the client id to use on the remote end of this bridge connection. If not
+# defined, this defaults to 'name.hostname' where name is the connection name
+# and hostname is the hostname of this computer.
+# This replaces the old "clientid" option to avoid confusion. "clientid"
+# remains valid for the time being.
+#remote_clientid
+
+# Set the password to use when connecting to a broker that requires
+# authentication. This option is only used if remote_username is also set.
+# This replaces the old "password" option to avoid confusion. "password"
+# remains valid for the time being.
+#remote_password
+
+# Set the username to use when connecting to a broker that requires
+# authentication.
+# This replaces the old "username" option to avoid confusion. "username"
+# remains valid for the time being.
+#remote_username
+
+# Set the amount of time a bridge using the automatic start type will wait
+# until attempting to reconnect.
+# This option can be configured to use a constant delay time in seconds, or to
+# use a backoff mechanism based on "Decorrelated Jitter", which adds a degree
+# of randomness to when the restart occurs.
+#
+# Set a constant timeout of 20 seconds:
+# restart_timeout 20
+#
+# Set backoff with a base (start value) of 10 seconds and a cap (upper limit) of
+# 60 seconds:
+# restart_timeout 10 30
+#
+# Defaults to jitter with a base of 5 and cap of 30
+#restart_timeout 5 30
+
+# If the bridge has more than one address given in the address/addresses
+# configuration, the round_robin option defines the behaviour of the bridge on
+# a failure of the bridge connection. If round_robin is false, the default
+# value, then the first address is treated as the main bridge connection. If
+# the connection fails, the other secondary addresses will be attempted in
+# turn. Whilst connected to a secondary bridge, the bridge will periodically
+# attempt to reconnect to the main bridge until successful.
+# If round_robin is true, then all addresses are treated as equals. If a
+# connection fails, the next address will be tried and if successful will
+# remain connected until it fails
+#round_robin false
+
+# Set the start type of the bridge. This controls how the bridge starts and
+# can be one of three types: automatic, lazy and once. Note that RSMB provides
+# a fourth start type "manual" which isn't currently supported by mosquitto.
+#
+# "automatic" is the default start type and means that the bridge connection
+# will be started automatically when the broker starts and also restarted
+# after a short delay (30 seconds) if the connection fails.
+#
+# Bridges using the "lazy" start type will be started automatically when the
+# number of queued messages exceeds the number set with the "threshold"
+# parameter. It will be stopped automatically after the time set by the
+# "idle_timeout" parameter. Use this start type if you wish the connection to
+# only be active when it is needed.
+#
+# A bridge using the "once" start type will be started automatically when the
+# broker starts but will not be restarted if the connection fails.
+#start_type automatic
+
+# Set the number of messages that need to be queued for a bridge with lazy
+# start type to be restarted. Defaults to 10 messages.
+# Must be less than max_queued_messages.
+#threshold 10
+
+# If try_private is set to true, the bridge will attempt to indicate to the
+# remote broker that it is a bridge not an ordinary client. If successful, this
+# means that loop detection will be more effective and that retained messages
+# will be propagated correctly. Not all brokers support this feature so it may
+# be necessary to set try_private to false if your bridge does not connect
+# properly.
+#try_private true
+
+# -----------------------------------------------------------------
+# Certificate based SSL/TLS support
+# -----------------------------------------------------------------
+# Either bridge_cafile or bridge_capath must be defined to enable TLS support
+# for this bridge.
+# bridge_cafile defines the path to a file containing the
+# Certificate Authority certificates that have signed the remote broker
+# certificate.
+# bridge_capath defines a directory that will be searched for files containing
+# the CA certificates. For bridge_capath to work correctly, the certificate
+# files must have ".crt" as the file ending and you must run "openssl rehash
+# <path to capath>" each time you add/remove a certificate.
+#bridge_cafile
+#bridge_capath
+
+
+# If the remote broker has more than one protocol available on its port, e.g.
+# MQTT and WebSockets, then use bridge_alpn to configure which protocol is
+# requested. Note that WebSockets support for bridges is not yet available.
+#bridge_alpn
+
+# When using certificate based encryption, bridge_insecure disables
+# verification of the server hostname in the server certificate. This can be
+# useful when testing initial server configurations, but makes it possible for
+# a malicious third party to impersonate your server through DNS spoofing, for
+# example. Use this option in testing only. If you need to resort to using this
+# option in a production environment, your setup is at fault and there is no
+# point using encryption.
+#bridge_insecure false
+
+# Path to the PEM encoded client certificate, if required by the remote broker.
+#bridge_certfile
+
+# Path to the PEM encoded client private key, if required by the remote broker.
+#bridge_keyfile
+
+# -----------------------------------------------------------------
+# PSK based SSL/TLS support
+# -----------------------------------------------------------------
+# Pre-shared-key encryption provides an alternative to certificate based
+# encryption. A bridge can be configured to use PSK with the bridge_identity
+# and bridge_psk options. These are the client PSK identity, and pre-shared-key
+# in hexadecimal format with no "0x". Only one of certificate and PSK based
+# encryption can be used on one
+# bridge at once.
+#bridge_identity
+#bridge_psk
+
+
+# =================================================================
+# External config files
+# =================================================================
+
+# External configuration files may be included by using the
+# include_dir option. This defines a directory that will be searched
+# for config files. All files that end in '.conf' will be loaded as
+# a configuration file. It is best to have this as the last option
+# in the main file. This option will only be processed from the main
+# configuration file. The directory specified must not contain the
+# main configuration file.
+# Files within include_dir will be loaded sorted in case-sensitive
+# alphabetical order, with capital letters ordered first. If this option is
+# given multiple times, all of the files from the first instance will be
+# processed before the next instance. See the man page for examples.
+#include_dir
diff --git a/examples/basyx.nodered/node-red-contrib-aas-connect/get-aas-property.html b/examples/basyx.nodered/node-red-contrib-aas-connect/get-aas-property.html
new file mode 100644
index 0000000..540724e
--- /dev/null
+++ b/examples/basyx.nodered/node-red-contrib-aas-connect/get-aas-property.html
@@ -0,0 +1,50 @@
+<script type="text/javascript">
+    RED.nodes.registerType('get-aas-property', {
+        category: 'network',
+        defaults: {
+            name: { value: '' },
+            property: { value: 'temperature', required: true },
+            period: { value: 1, required: true }
+        },
+        inputs: 1,
+        outputs: 1,
+        color: '#C3D6F2',
+        align: 'left',
+        label: function() {
+            return this.name || "Get AAS property";
+        },
+        palettelabel: function() {
+            return this.name || "Get AAS property";
+        },
+        icon: 'logo-BaSys4.png',
+    })
+</script>
+
+<script type="text/html" data-template-name="get-aas-property">
+    <div class="form-row">
+        <label for="node-input-name"><i class="fa fa-tag"></i> Node name</label>
+        <input type="text" id="node-input-name" placeholder="Name">
+    </div>
+    <div class="form-row">
+        <label for="node-input-property"><i class="fa fa-rss"></i> Property</label>
+        <input type="text" id="node-input-property" placeholder="Property">
+    </div>
+    <div class="form-row">
+        <label for="node-input-period">
+            <i class="fa fa-clock-o"></i> Interval <br/><span style="font-size:0.8em">(in seconds)</span>
+        </label>
+        <input type="text" id="node-input-period" placeholder="Interval">
+    </div>
+    <!-- <div class="form-tips"><b>Tip:</b> This is here to help.</div> -->
+</script>
+
+<script type="text/html" data-help-name="get-aas-property">
+    <p>This node monitors (periodically retrives) the value of an AAS property</p>
+    <h3>Outputs</h3>
+    <dl class="message-properties">
+        <dt>payload
+            <span class="property-type">object</span>
+        </dt>
+        <dd> the payload of the message containing the property value (in the 'value' key) and the timestamp (in the 'tstamp' key). </dd>
+    </dl>
+ </script>
\ No newline at end of file
diff --git a/examples/basyx.nodered/node-red-contrib-aas-connect/get-aas-property.js b/examples/basyx.nodered/node-red-contrib-aas-connect/get-aas-property.js
new file mode 100644
index 0000000..09fdd0e
--- /dev/null
+++ b/examples/basyx.nodered/node-red-contrib-aas-connect/get-aas-property.js
@@ -0,0 +1,60 @@
+module.exports = function(RED) {
+
+    const request = require('request');
+
+    function GetAASProperty(config) {
+        let property = config.property || 'temp';
+        let endpoint = `http://aas-wrapper:6500/streamsheets/${property}`;
+        let period = Number(config.period) || 1;
+        let msperiod = period * 1000;
+
+        RED.nodes.createNode(this, config);
+
+        let node = this;
+        let interval;
+        node.on('input', function(msg, send, done) {
+            interval = setInterval(() => {
+                request(endpoint, { json: true }, (err, res, body) => {
+                    if (err) {
+                        node.error(err);
+                        if (done) done(err);
+                        return;
+                    }
+
+                    if (!body.success) {
+                        node.error(body.messages);
+                        if (done) done(body.messages);
+                        return;
+                    }
+
+                    // let mostRecentTimestamp = body.timestamp.pop();
+                    // let mostRecentValue = body.content.pop();
+
+                    let data = {
+                        tstamp: body.timestamp,
+                        data: body.content,
+                    }
+                    
+                    msg.payload = data;
+
+                    // For maximum backwards compatibility, check that send exists.
+                    // If this node is installed in Node-RED 0.x, it will need to
+                    // fallback to using `node.send`
+                    send = send || function() { node.send.apply(node, msg) }
+                    send(msg);
+
+                    if (done) done();
+                });
+            }, msperiod);
+
+        });
+
+        node.on('close', function(done) {
+            clearInterval(interval);
+            if (done) done();
+        });
+
+    }
+
+    RED.nodes.registerType('get-aas-property', GetAASProperty);
+}
\ No newline at end of file
diff --git a/examples/basyx.nodered/node-red-contrib-aas-connect/icons/logo-BaSys4.png b/examples/basyx.nodered/node-red-contrib-aas-connect/icons/logo-BaSys4.png
new file mode 100644
index 0000000..56d0dac
--- /dev/null
+++ b/examples/basyx.nodered/node-red-contrib-aas-connect/icons/logo-BaSys4.png
Binary files differ
diff --git a/examples/basyx.nodered/node-red-contrib-aas-connect/icons/machine.png b/examples/basyx.nodered/node-red-contrib-aas-connect/icons/machine.png
new file mode 100644
index 0000000..56db813
--- /dev/null
+++ b/examples/basyx.nodered/node-red-contrib-aas-connect/icons/machine.png
Binary files differ
diff --git a/examples/basyx.nodered/node-red-contrib-aas-connect/package.json b/examples/basyx.nodered/node-red-contrib-aas-connect/package.json
new file mode 100644
index 0000000..882bb64
--- /dev/null
+++ b/examples/basyx.nodered/node-red-contrib-aas-connect/package.json
@@ -0,0 +1,20 @@
+{
+  "name": "node-red-contrib-aas-connect",
+  "version": "1.0.0",
+  "description": "",
+  "main": "get-aas-property.js",
+  "scripts": {
+    "test": "echo \"Error: no test specified\" && exit 1"
+  },
+  "node-red": {
+    "nodes": {
+      "get-aas-property": "get-aas-property.js",
+      "set-aas-property": "set-aas-property.js"
+    }
+  },
+  "author": "",
+  "license": "ISC",
+  "dependencies": {
+    "request": "^2.88.2"
+  }
+}
diff --git a/examples/basyx.nodered/node-red-contrib-aas-connect/set-aas-property.html b/examples/basyx.nodered/node-red-contrib-aas-connect/set-aas-property.html
new file mode 100644
index 0000000..db9b93a
--- /dev/null
+++ b/examples/basyx.nodered/node-red-contrib-aas-connect/set-aas-property.html
@@ -0,0 +1,36 @@
+<script type="text/javascript">
+    RED.nodes.registerType('set-aas-property', {
+        category: 'network',
+        defaults: {
+            name: { value: '' },
+            property: { value: 'temp', required: true },
+        },
+        inputs: 1,
+        outputs: 0,
+        color: '#C3D6F2',
+        align: 'right',
+        label: function() {
+            return this.name || "Set AAS property";
+        },
+        palettelabel: function() {
+            return this.name || "Set AAS property";
+        },
+        icon: 'logo-BaSys4.png',
+    })
+</script>
+
+<script type="text/html" data-template-name="set-aas-property">
+    <div class="form-row">
+        <label for="node-input-name"><i class="fa fa-tag"></i> Node name</label>
+        <input type="text" id="node-input-name" placeholder="Name">
+    </div>
+    <div class="form-row">
+        <label for="node-input-property"><i class="fa fa-rss"></i> Property</label>
+        <input type="text" id="node-input-property" placeholder="Property">
+    </div>
+    <!-- <div class="form-tips"><b>Tip:</b> This is here to help.</div> -->
+</script>
+
+<script type="text/html" data-help-name="set-aas-property">
+    <p>This node sets the value of an AAS property</p>
+ </script>
\ No newline at end of file
diff --git a/examples/basyx.nodered/node-red-contrib-aas-connect/set-aas-property.js b/examples/basyx.nodered/node-red-contrib-aas-connect/set-aas-property.js
new file mode 100644
index 0000000..d8af768
--- /dev/null
+++ b/examples/basyx.nodered/node-red-contrib-aas-connect/set-aas-property.js
@@ -0,0 +1,40 @@
+module.exports = function(RED) {
+
+    const request = require('request');
+
+    function SetAASProperty(config) {
+        let property = config.property || 'temp';
+        let endpoint = `http://aas-wrapper:6500/streamsheets/${property}`;
+
+        RED.nodes.createNode(this, config);
+
+        let node = this;
+        node.on('input', function(msg, send, done) {
+            let newValue = msg.payload;
+
+            request({
+                uri: endpoint,
+                method: 'POST',
+                json: true,
+                body: { value: newValue }
+            }, (err, res, body) => {
+                if (err) {
+                    node.error(err);
+                    if (done) done(err);
+                    return;
+                }
+
+                if (!body.success) {
+                    node.error(body.error);
+                    if (done) done(body.error);
+                    return;
+                }
+
+                if (done) done();
+            });
+        });
+    }
+
+    RED.nodes.registerType('set-aas-property', SetAASProperty);
+
+}
\ No newline at end of file
diff --git a/examples/basyx.nodered/node-red/.config.json b/examples/basyx.nodered/node-red/.config.json
new file mode 100644
index 0000000..c8d13d4
--- /dev/null
+++ b/examples/basyx.nodered/node-red/.config.json
@@ -0,0 +1,456 @@
+{
+ "nodes": {
+  "node-red": {
+   "name": "node-red",
+   "version": "1.1.2",
+   "local": false,
+   "nodes": {
+    "inject": {
+     "name": "inject",
+     "types": [
+      "inject"
+     ],
+     "enabled": true,
+     "local": false,
+     "module": "node-red",
+     "file": "/usr/src/node-red/node_modules/@node-red/nodes/core/common/20-inject.js"
+    },
+    "debug": {
+     "name": "debug",
+     "types": [
+      "debug"
+     ],
+     "enabled": true,
+     "local": false,
+     "module": "node-red",
+     "file": "/usr/src/node-red/node_modules/@node-red/nodes/core/common/21-debug.js"
+    },
+    "complete": {
+     "name": "complete",
+     "types": [
+      "complete"
+     ],
+     "enabled": true,
+     "local": false,
+     "module": "node-red",
+     "file": "/usr/src/node-red/node_modules/@node-red/nodes/core/common/24-complete.js"
+    },
+    "catch": {
+     "name": "catch",
+     "types": [
+      "catch"
+     ],
+     "enabled": true,
+     "local": false,
+     "module": "node-red",
+     "file": "/usr/src/node-red/node_modules/@node-red/nodes/core/common/25-catch.js"
+    },
+    "status": {
+     "name": "status",
+     "types": [
+      "status"
+     ],
+     "enabled": true,
+     "local": false,
+     "module": "node-red",
+     "file": "/usr/src/node-red/node_modules/@node-red/nodes/core/common/25-status.js"
+    },
+    "link": {
+     "name": "link",
+     "types": [
+      "link in",
+      "link out"
+     ],
+     "enabled": true,
+     "local": false,
+     "module": "node-red",
+     "file": "/usr/src/node-red/node_modules/@node-red/nodes/core/common/60-link.js"
+    },
+    "comment": {
+     "name": "comment",
+     "types": [
+      "comment"
+     ],
+     "enabled": true,
+     "local": false,
+     "module": "node-red",
+     "file": "/usr/src/node-red/node_modules/@node-red/nodes/core/common/90-comment.js"
+    },
+    "unknown": {
+     "name": "unknown",
+     "types": [
+      "unknown"
+     ],
+     "enabled": true,
+     "local": false,
+     "module": "node-red",
+     "file": "/usr/src/node-red/node_modules/@node-red/nodes/core/common/98-unknown.js"
+    },
+    "function": {
+     "name": "function",
+     "types": [
+      "function"
+     ],
+     "enabled": true,
+     "local": false,
+     "module": "node-red",
+     "file": "/usr/src/node-red/node_modules/@node-red/nodes/core/function/10-function.js"
+    },
+    "switch": {
+     "name": "switch",
+     "types": [
+      "switch"
+     ],
+     "enabled": true,
+     "local": false,
+     "module": "node-red",
+     "file": "/usr/src/node-red/node_modules/@node-red/nodes/core/function/10-switch.js"
+    },
+    "change": {
+     "name": "change",
+     "types": [
+      "change"
+     ],
+     "enabled": true,
+     "local": false,
+     "module": "node-red",
+     "file": "/usr/src/node-red/node_modules/@node-red/nodes/core/function/15-change.js"
+    },
+    "range": {
+     "name": "range",
+     "types": [
+      "range"
+     ],
+     "enabled": true,
+     "local": false,
+     "module": "node-red",
+     "file": "/usr/src/node-red/node_modules/@node-red/nodes/core/function/16-range.js"
+    },
+    "template": {
+     "name": "template",
+     "types": [
+      "template"
+     ],
+     "enabled": true,
+     "local": false,
+     "module": "node-red",
+     "file": "/usr/src/node-red/node_modules/@node-red/nodes/core/function/80-template.js"
+    },
+    "delay": {
+     "name": "delay",
+     "types": [
+      "delay"
+     ],
+     "enabled": true,
+     "local": false,
+     "module": "node-red",
+     "file": "/usr/src/node-red/node_modules/@node-red/nodes/core/function/89-delay.js"
+    },
+    "trigger": {
+     "name": "trigger",
+     "types": [
+      "trigger"
+     ],
+     "enabled": true,
+     "local": false,
+     "module": "node-red",
+     "file": "/usr/src/node-red/node_modules/@node-red/nodes/core/function/89-trigger.js"
+    },
+    "exec": {
+     "name": "exec",
+     "types": [
+      "exec"
+     ],
+     "enabled": true,
+     "local": false,
+     "module": "node-red",
+     "file": "/usr/src/node-red/node_modules/@node-red/nodes/core/function/90-exec.js"
+    },
+    "tls": {
+     "name": "tls",
+     "types": [
+      "tls-config"
+     ],
+     "enabled": true,
+     "local": false,
+     "module": "node-red",
+     "file": "/usr/src/node-red/node_modules/@node-red/nodes/core/network/05-tls.js"
+    },
+    "httpproxy": {
+     "name": "httpproxy",
+     "types": [
+      "http proxy"
+     ],
+     "enabled": true,
+     "local": false,
+     "module": "node-red",
+     "file": "/usr/src/node-red/node_modules/@node-red/nodes/core/network/06-httpproxy.js"
+    },
+    "mqtt": {
+     "name": "mqtt",
+     "types": [
+      "mqtt in",
+      "mqtt out",
+      "mqtt-broker"
+     ],
+     "enabled": true,
+     "local": false,
+     "module": "node-red",
+     "file": "/usr/src/node-red/node_modules/@node-red/nodes/core/network/10-mqtt.js"
+    },
+    "httpin": {
+     "name": "httpin",
+     "types": [
+      "http in",
+      "http response"
+     ],
+     "enabled": true,
+     "local": false,
+     "module": "node-red",
+     "file": "/usr/src/node-red/node_modules/@node-red/nodes/core/network/21-httpin.js"
+    },
+    "httprequest": {
+     "name": "httprequest",
+     "types": [
+      "http request"
+     ],
+     "enabled": true,
+     "local": false,
+     "module": "node-red",
+     "file": "/usr/src/node-red/node_modules/@node-red/nodes/core/network/21-httprequest.js"
+    },
+    "websocket": {
+     "name": "websocket",
+     "types": [
+      "websocket in",
+      "websocket out",
+      "websocket-listener",
+      "websocket-client"
+     ],
+     "enabled": true,
+     "local": false,
+     "module": "node-red",
+     "file": "/usr/src/node-red/node_modules/@node-red/nodes/core/network/22-websocket.js"
+    },
+    "tcpin": {
+     "name": "tcpin",
+     "types": [
+      "tcp in",
+      "tcp out",
+      "tcp request"
+     ],
+     "enabled": true,
+     "local": false,
+     "module": "node-red",
+     "file": "/usr/src/node-red/node_modules/@node-red/nodes/core/network/31-tcpin.js"
+    },
+    "udp": {
+     "name": "udp",
+     "types": [
+      "udp in",
+      "udp out"
+     ],
+     "enabled": true,
+     "local": false,
+     "module": "node-red",
+     "file": "/usr/src/node-red/node_modules/@node-red/nodes/core/network/32-udp.js"
+    },
+    "CSV": {
+     "name": "CSV",
+     "types": [
+      "csv"
+     ],
+     "enabled": true,
+     "local": false,
+     "module": "node-red",
+     "file": "/usr/src/node-red/node_modules/@node-red/nodes/core/parsers/70-CSV.js"
+    },
+    "HTML": {
+     "name": "HTML",
+     "types": [
+      "html"
+     ],
+     "enabled": true,
+     "local": false,
+     "module": "node-red",
+     "file": "/usr/src/node-red/node_modules/@node-red/nodes/core/parsers/70-HTML.js"
+    },
+    "JSON": {
+     "name": "JSON",
+     "types": [
+      "json"
+     ],
+     "enabled": true,
+     "local": false,
+     "module": "node-red",
+     "file": "/usr/src/node-red/node_modules/@node-red/nodes/core/parsers/70-JSON.js"
+    },
+    "XML": {
+     "name": "XML",
+     "types": [
+      "xml"
+     ],
+     "enabled": true,
+     "local": false,
+     "module": "node-red",
+     "file": "/usr/src/node-red/node_modules/@node-red/nodes/core/parsers/70-XML.js"
+    },
+    "YAML": {
+     "name": "YAML",
+     "types": [
+      "yaml"
+     ],
+     "enabled": true,
+     "local": false,
+     "module": "node-red",
+     "file": "/usr/src/node-red/node_modules/@node-red/nodes/core/parsers/70-YAML.js"
+    },
+    "split": {
+     "name": "split",
+     "types": [
+      "split",
+      "join"
+     ],
+     "enabled": true,
+     "local": false,
+     "module": "node-red",
+     "file": "/usr/src/node-red/node_modules/@node-red/nodes/core/sequence/17-split.js"
+    },
+    "sort": {
+     "name": "sort",
+     "types": [
+      "sort"
+     ],
+     "enabled": true,
+     "local": false,
+     "module": "node-red",
+     "file": "/usr/src/node-red/node_modules/@node-red/nodes/core/sequence/18-sort.js"
+    },
+    "batch": {
+     "name": "batch",
+     "types": [
+      "batch"
+     ],
+     "enabled": true,
+     "local": false,
+     "module": "node-red",
+     "file": "/usr/src/node-red/node_modules/@node-red/nodes/core/sequence/19-batch.js"
+    },
+    "file": {
+     "name": "file",
+     "types": [
+      "file",
+      "file in"
+     ],
+     "enabled": true,
+     "local": false,
+     "module": "node-red",
+     "file": "/usr/src/node-red/node_modules/@node-red/nodes/core/storage/10-file.js"
+    },
+    "watch": {
+     "name": "watch",
+     "types": [
+      "watch"
+     ],
+     "enabled": true,
+     "local": false,
+     "module": "node-red",
+     "file": "/usr/src/node-red/node_modules/@node-red/nodes/core/storage/23-watch.js"
+    }
+   }
+  },
+  "node-red-contrib-aas-connect": {
+   "name": "node-red-contrib-aas-connect",
+   "version": "1.0.0",
+   "local": false,
+   "nodes": {
+    "get-aas-property": {
+     "name": "get-aas-property",
+     "types": [
+      "get-aas-property"
+     ],
+     "enabled": true,
+     "local": false,
+     "module": "node-red-contrib-aas-connect",
+     "file": "/usr/src/node-red/node_modules/node-red-contrib-aas-connect/get-aas-property.js"
+    },
+    "set-aas-property": {
+     "name": "set-aas-property",
+     "types": [
+      "set-aas-property"
+     ],
+     "enabled": true,
+     "local": false,
+     "module": "node-red-contrib-aas-connect",
+     "file": "/usr/src/node-red/node_modules/node-red-contrib-aas-connect/set-aas-property.js"
+    }
+   }
+  },
+  "node-red-contrib-graphs": {
+   "name": "node-red-contrib-graphs",
+   "version": "0.3.5",
+   "local": false,
+   "nodes": {
+    "datasource": {
+     "name": "datasource",
+     "types": [
+      "iot-datasource"
+     ],
+     "enabled": true,
+     "local": false,
+     "module": "node-red-contrib-graphs",
+     "file": "/usr/src/node-red/node_modules/node-red-contrib-graphs/datasource.js"
+    }
+   }
+  },
+  "node-red-node-rbe": {
+   "name": "node-red-node-rbe",
+   "version": "0.2.9",
+   "local": false,
+   "nodes": {
+    "rbe": {
+     "name": "rbe",
+     "types": [
+      "rbe"
+     ],
+     "enabled": true,
+     "local": false,
+     "module": "node-red-node-rbe",
+     "file": "/usr/src/node-red/node_modules/node-red-node-rbe/rbe.js"
+    }
+   }
+  },
+  "node-red-node-tail": {
+   "name": "node-red-node-tail",
+   "version": "0.1.1",
+   "local": false,
+   "nodes": {
+    "tail": {
+     "name": "tail",
+     "types": [
+      "tail"
+     ],
+     "enabled": true,
+     "local": false,
+     "module": "node-red-node-tail",
+     "file": "/usr/src/node-red/node_modules/node-red-node-tail/28-tail.js"
+    }
+   }
+  }
+ },
+ "_credentialSecret": "c028885f2cb96099498adca00919db2df73313d916d037a5a1c8eb931b43c03e",
+ "users": {
+  "_": {
+   "editor": {
+    "view": {
+     "view-show-grid": true,
+     "view-snap-grid": true,
+     "view-grid-size": 20,
+     "view-node-status": true,
+     "view-node-show-label": true,
+     "view-show-tips": false
+    }
+   }
+  }
+ }
+}
\ No newline at end of file
diff --git a/examples/basyx.nodered/node-red/.dash/config_default.json b/examples/basyx.nodered/node-red/.dash/config_default.json
new file mode 100644
index 0000000..711d715
--- /dev/null
+++ b/examples/basyx.nodered/node-red/.dash/config_default.json
@@ -0,0 +1,3 @@
+{
+	"dashboards": []
+}
\ No newline at end of file
diff --git a/examples/basyx.nodered/node-red/flows.json b/examples/basyx.nodered/node-red/flows.json
new file mode 100644
index 0000000..b4063b1
--- /dev/null
+++ b/examples/basyx.nodered/node-red/flows.json
@@ -0,0 +1 @@
+[{"id":"ac89e902.a48598","type":"tab","label":"AAS Temperature","disabled":false,"info":""},{"id":"91383a96.5b2e48","type":"tab","label":"Test","disabled":false,"info":""},{"id":"1b4daff8.52358","type":"mqtt-broker","z":"","name":"Mosquitto","broker":"http://mosquitto","port":"1883","clientid":"","usetls":false,"compatmode":false,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""},{"id":"2289cf21.0a21b","type":"inject","z":"ac89e902.a48598","name":"Start","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":110,"y":120,"wires":[["c3659321.46995"]]},{"id":"c3659321.46995","type":"get-aas-property","z":"ac89e902.a48598","name":"Get Temperature","property":"temp","period":1,"x":270,"y":120,"wires":[["a56bd8e1.1777c8","2c13d59c.208cea","8c41e115.ac913"]]},{"id":"4e72f0db.c2a7a","type":"inject","z":"91383a96.5b2e48","name":"Data","props":[{"p":"values","v":"[22.344,23.434,24.342,21.098]","vt":"json"},{"p":"timestamp","v":"[121323,2112231,321331,321321]","vt":"json"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":140,"y":100,"wires":[["a53d7930.6109f8","4a734a5f.b22314","ab2d648a.1767f8"]]},{"id":"a53d7930.6109f8","type":"debug","z":"91383a96.5b2e48","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":250,"y":240,"wires":[]},{"id":"4a734a5f.b22314","type":"function","z":"91383a96.5b2e48","name":"Calculate Average","func":"msg.avg = msg.values.reduce((a,b) => a + b, 0) / msg.values.length;\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":450,"y":120,"wires":[["6b28c27b.5547bc"]]},{"id":"6b28c27b.5547bc","type":"debug","z":"91383a96.5b2e48","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":710,"y":120,"wires":[]},{"id":"ab2d648a.1767f8","type":"function","z":"91383a96.5b2e48","name":"Calculate Fahrenheit","func":"msg.fahrenheit = msg.values.map(v => v * 1.8 + 32);\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":460,"y":180,"wires":[["5e614070.a223f"]]},{"id":"5e614070.a223f","type":"debug","z":"91383a96.5b2e48","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":710,"y":180,"wires":[]},{"id":"e733d05.63a9c3","type":"iot-datasource","z":"ac89e902.a48598","name":"Temperature Datasource","tstampField":"tstamp","dataField":"data","disableDiscover":false,"x":730,"y":240,"wires":[[]]},{"id":"8e627da8.65b74","type":"mqtt out","z":"ac89e902.a48598","name":"MQTT Avg Temp Publisher","topic":"temperature/average","qos":"","retain":"","broker":"1b4daff8.52358","x":740,"y":120,"wires":[]},{"id":"7aa9e937.6575c8","type":"mqtt in","z":"ac89e902.a48598","name":"MQTT Avg Temp Consumer","topic":"temperature/average","qos":"2","datatype":"json","broker":"1b4daff8.52358","x":160,"y":360,"wires":[["f96c72b.3be659"]]},{"id":"f96c72b.3be659","type":"debug","z":"ac89e902.a48598","name":"Msg","active":true,"tosidebar":true,"console":true,"tostatus":true,"complete":"payload.average","targetType":"msg","statusVal":"payload.average","statusType":"auto","x":390,"y":360,"wires":[]},{"id":"a56bd8e1.1777c8","type":"function","z":"ac89e902.a48598","name":"Calculate Average","func":"const payload = msg.payload;\nlet average = payload.data.reduce((a,b) => a + b, 0) / payload.data.length;\npayload.average = average;\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":490,"y":120,"wires":[["8e627da8.65b74"]]},{"id":"2c13d59c.208cea","type":"function","z":"ac89e902.a48598","name":"Calculate Fahrenheit","func":"const payload = msg.payload;\nlet fahrenheit = payload.data.map(v => v * 1.8 + 32);\npayload.fahrenheit = fahrenheit;\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":500,"y":180,"wires":[["a3733cf8.97468"]]},{"id":"a3733cf8.97468","type":"mqtt out","z":"ac89e902.a48598","name":"MQTT Fahrenheit Temp Publisher","topic":"temperature/fahrenheit","qos":"","retain":"","broker":"1b4daff8.52358","x":760,"y":180,"wires":[]},{"id":"8c41e115.ac913","type":"function","z":"ac89e902.a48598","name":"Get most recent","func":"msg.payload.tstamp = new Date(msg.payload.tstamp.pop()).getTime();\nmsg.payload.data = msg.payload.data.pop();\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":480,"y":240,"wires":[["e733d05.63a9c3"]]}]
\ No newline at end of file
diff --git a/examples/basyx.nodered/node-red/flows_cred.json b/examples/basyx.nodered/node-red/flows_cred.json
new file mode 100644
index 0000000..a4c98fe
--- /dev/null
+++ b/examples/basyx.nodered/node-red/flows_cred.json
@@ -0,0 +1 @@
+{"$":"c868da21da8ba53a0c91801df18843d0H2SPE/Z3kkH48hmjwFw92jPiFRST"}
\ No newline at end of file
diff --git a/examples/basyx.nodered/node-red/package.json b/examples/basyx.nodered/node-red/package.json
new file mode 100644
index 0000000..b788fd4
--- /dev/null
+++ b/examples/basyx.nodered/node-red/package.json
@@ -0,0 +1,6 @@
+{
+    "name": "node-red-project",
+    "description": "A Node-RED Project",
+    "version": "0.0.1",
+    "private": true
+}
\ No newline at end of file
diff --git a/examples/basyx.nodered/node-red/settings.js b/examples/basyx.nodered/node-red/settings.js
new file mode 100644
index 0000000..f3c93f5
--- /dev/null
+++ b/examples/basyx.nodered/node-red/settings.js
@@ -0,0 +1,299 @@
+/**
+ * Copyright JS Foundation and other contributors, http://js.foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ **/
+
+module.exports = {
+    // the tcp port that the Node-RED web server is listening on
+    uiPort: process.env.PORT || 1880,
+
+    // By default, the Node-RED UI accepts connections on all IPv4 interfaces.
+    // To listen on all IPv6 addresses, set uiHost to "::",
+    // The following property can be used to listen on a specific interface. For
+    // example, the following would only allow connections from the local machine.
+    //uiHost: "127.0.0.1",
+
+    // Retry time in milliseconds for MQTT connections
+    mqttReconnectTime: 15000,
+
+    // Retry time in milliseconds for Serial port connections
+    serialReconnectTime: 15000,
+
+    // Retry time in milliseconds for TCP socket connections
+    //socketReconnectTime: 10000,
+
+    // Timeout in milliseconds for TCP server socket connections
+    //  defaults to no timeout
+    //socketTimeout: 120000,
+
+    // Maximum number of messages to wait in queue while attempting to connect to TCP socket
+    //  defaults to 1000
+    //tcpMsgQueueSize: 2000,
+
+    // Timeout in milliseconds for HTTP request connections
+    //  defaults to 120 seconds
+    //httpRequestTimeout: 120000,
+
+    // The maximum length, in characters, of any message sent to the debug sidebar tab
+    debugMaxLength: 1000,
+
+    // The maximum number of messages nodes will buffer internally as part of their
+    // operation. This applies across a range of nodes that operate on message sequences.
+    //  defaults to no limit. A value of 0 also means no limit is applied.
+    //nodeMessageBufferMaxLength: 0,
+
+    // To disable the option for using local files for storing keys and certificates in the TLS configuration
+    //  node, set this to true
+    //tlsConfigDisableLocalFiles: true,
+
+    // Colourise the console output of the debug node
+    //debugUseColors: true,
+
+    // The file containing the flows. If not set, it defaults to flows_<hostname>.json
+    //flowFile: 'flows.json',
+
+    // To enabled pretty-printing of the flow within the flow file, set the following
+    //  property to true:
+    //flowFilePretty: true,
+
+    // By default, credentials are encrypted in storage using a generated key. To
+    // specify your own secret, set the following property.
+    // If you want to disable encryption of credentials, set this property to false.
+    // Note: once you set this property, do not change it - doing so will prevent
+    // node-red from being able to decrypt your existing credentials and they will be
+    // lost.
+    //credentialSecret: "a-secret-key",
+
+    // By default, all user data is stored in a directory called `.node-red` under
+    // the user's home directory. To use a different location, the following
+    // property can be used
+    //userDir: '/home/nol/.node-red/',
+
+    // Node-RED scans the `nodes` directory in the userDir to find local node files.
+    // The following property can be used to specify an additional directory to scan.
+    //nodesDir: '/home/nol/.node-red/nodes',
+
+    // By default, the Node-RED UI is available at http://localhost:1880/
+    // The following property can be used to specify a different root path.
+    // If set to false, this is disabled.
+    //httpAdminRoot: '/admin',
+
+    // Some nodes, such as HTTP In, can be used to listen for incoming http requests.
+    // By default, these are served relative to '/'. The following property
+    // can be used to specifiy a different root path. If set to false, this is
+    // disabled.
+    //httpNodeRoot: '/red-nodes',
+
+    // The following property can be used in place of 'httpAdminRoot' and 'httpNodeRoot',
+    // to apply the same root to both parts.
+    //httpRoot: '/red',
+
+    // When httpAdminRoot is used to move the UI to a different root path, the
+    // following property can be used to identify a directory of static content
+    // that should be served at http://localhost:1880/.
+    //httpStatic: '/home/nol/node-red-static/',
+
+    // The maximum size of HTTP request that will be accepted by the runtime api.
+    // Default: 5mb
+    //apiMaxLength: '5mb',
+
+    // If you installed the optional node-red-dashboard you can set it's path
+    // relative to httpRoot
+    //ui: { path: "ui" },
+
+    // Securing Node-RED
+    // -----------------
+    // To password protect the Node-RED editor and admin API, the following
+    // property can be used. See http://nodered.org/docs/security.html for details.
+    //adminAuth: {
+    //    type: "credentials",
+    //    users: [{
+    //        username: "admin",
+    //        password: "$2a$08$zZWtXTja0fB1pzD4sHCMyOCMYz2Z6dNbM6tl8sJogENOMcxWV9DN.",
+    //        permissions: "*"
+    //    }]
+    //},
+
+    // To password protect the node-defined HTTP endpoints (httpNodeRoot), or
+    // the static content (httpStatic), the following properties can be used.
+    // The pass field is a bcrypt hash of the password.
+    // See http://nodered.org/docs/security.html#generating-the-password-hash
+    //httpNodeAuth: {user:"user",pass:"$2a$08$zZWtXTja0fB1pzD4sHCMyOCMYz2Z6dNbM6tl8sJogENOMcxWV9DN."},
+    //httpStaticAuth: {user:"user",pass:"$2a$08$zZWtXTja0fB1pzD4sHCMyOCMYz2Z6dNbM6tl8sJogENOMcxWV9DN."},
+
+    // The following property can be used to enable HTTPS
+    // See http://nodejs.org/api/https.html#https_https_createserver_options_requestlistener
+    // for details on its contents.
+    // This property can be either an object, containing both a (private) key and a (public) certificate,
+    // or a function that returns such an object:
+    //// https object:
+    //https: {
+    //  key: require("fs").readFileSync('privkey.pem'),
+    //  cert: require("fs").readFileSync('cert.pem')
+    //},
+    ////https function:
+    // https: function() {
+    //     // This function should return the options object, or a Promise
+    //     // that resolves to the options object
+    //     return {
+    //         key: require("fs").readFileSync('privkey.pem'),
+    //         cert: require("fs").readFileSync('cert.pem')
+    //     }
+    // },
+
+    // The following property can be used to refresh the https settings at a
+    // regular time interval in hours.
+    // This requires:
+    //   - the `https` setting to be a function that can be called to get
+    //     the refreshed settings.
+    //   - Node.js 11 or later.
+    //httpsRefreshInterval : 12,
+
+    // The following property can be used to cause insecure HTTP connections to
+    // be redirected to HTTPS.
+    //requireHttps: true,
+
+    // The following property can be used to disable the editor. The admin API
+    // is not affected by this option. To disable both the editor and the admin
+    // API, use either the httpRoot or httpAdminRoot properties
+    //disableEditor: false,
+
+    // The following property can be used to configure cross-origin resource sharing
+    // in the HTTP nodes.
+    // See https://github.com/troygoode/node-cors#configuration-options for
+    // details on its contents. The following is a basic permissive set of options:
+    //httpNodeCors: {
+    //    origin: "*",
+    //    methods: "GET,PUT,POST,DELETE"
+    //},
+
+    // If you need to set an http proxy please set an environment variable
+    // called http_proxy (or HTTP_PROXY) outside of Node-RED in the operating system.
+    // For example - http_proxy=http://myproxy.com:8080
+    // (Setting it here will have no effect)
+    // You may also specify no_proxy (or NO_PROXY) to supply a comma separated
+    // list of domains to not proxy, eg - no_proxy=.acme.co,.acme.co.uk
+
+    // The following property can be used to add a custom middleware function
+    // in front of all http in nodes. This allows custom authentication to be
+    // applied to all http in nodes, or any other sort of common request processing.
+    //httpNodeMiddleware: function(req,res,next) {
+    //    // Handle/reject the request, or pass it on to the http in node by calling next();
+    //    // Optionally skip our rawBodyParser by setting this to true;
+    //    //req.skipRawBodyParser = true;
+    //    next();
+    //},
+
+
+    // The following property can be used to add a custom middleware function
+    // in front of all admin http routes. For example, to set custom http
+    // headers
+    // httpAdminMiddleware: function(req,res,next) {
+    //    // Set the X-Frame-Options header to limit where the editor
+    //    // can be embedded
+    //    //res.set('X-Frame-Options', 'sameorigin');
+    //    next();
+    // },
+
+    // The following property can be used to pass custom options to the Express.js
+    // server used by Node-RED. For a full list of available options, refer
+    // to http://expressjs.com/en/api.html#app.settings.table
+    //httpServerOptions: { },
+
+    // The following property can be used to verify websocket connection attempts.
+    // This allows, for example, the HTTP request headers to be checked to ensure
+    // they include valid authentication information.
+    //webSocketNodeVerifyClient: function(info) {
+    //    // 'info' has three properties:
+    //    //   - origin : the value in the Origin header
+    //    //   - req : the HTTP request
+    //    //   - secure : true if req.connection.authorized or req.connection.encrypted is set
+    //    //
+    //    // The function should return true if the connection should be accepted, false otherwise.
+    //    //
+    //    // Alternatively, if this function is defined to accept a second argument, callback,
+    //    // it can be used to verify the client asynchronously.
+    //    // The callback takes three arguments:
+    //    //   - result : boolean, whether to accept the connection or not
+    //    //   - code : if result is false, the HTTP error status to return
+    //    //   - reason: if result is false, the HTTP reason string to return
+    //},
+
+    // The following property can be used to seed Global Context with predefined
+    // values. This allows extra node modules to be made available with the
+    // Function node.
+    // For example,
+    //    functionGlobalContext: { os:require('os') }
+    // can be accessed in a function block as:
+    //    global.get("os")
+    functionGlobalContext: {
+        // os:require('os'),
+        // jfive:require("johnny-five"),
+        // j5board:require("johnny-five").Board({repl:false})
+    },
+    // `global.keys()` returns a list of all properties set in global context.
+    // This allows them to be displayed in the Context Sidebar within the editor.
+    // In some circumstances it is not desirable to expose them to the editor. The
+    // following property can be used to hide any property set in `functionGlobalContext`
+    // from being list by `global.keys()`.
+    // By default, the property is set to false to avoid accidental exposure of
+    // their values. Setting this to true will cause the keys to be listed.
+    exportGlobalContextKeys: false,
+
+
+    // Context Storage
+    // The following property can be used to enable context storage. The configuration
+    // provided here will enable file-based context that flushes to disk every 30 seconds.
+    // Refer to the documentation for further options: https://nodered.org/docs/api/context/
+    //
+    //contextStorage: {
+    //    default: {
+    //        module:"localfilesystem"
+    //    },
+    //},
+
+    // The following property can be used to order the categories in the editor
+    // palette. If a node's category is not in the list, the category will get
+    // added to the end of the palette.
+    // If not set, the following default order is used:
+    //paletteCategories: ['subflows', 'common', 'function', 'network', 'sequence', 'parser', 'storage'],
+
+    // Configure the logging output
+    logging: {
+        // Only console logging is currently supported
+        console: {
+            // Level of logging to be recorded. Options are:
+            // fatal - only those errors which make the application unusable should be recorded
+            // error - record errors which are deemed fatal for a particular request + fatal errors
+            // warn - record problems which are non fatal + errors + fatal errors
+            // info - record information about the general running of the application + warn + error + fatal errors
+            // debug - record information which is more verbose than info + info + warn + error + fatal errors
+            // trace - record very detailed logging + debug + info + warn + error + fatal errors
+            // off - turn off all logging (doesn't affect metrics or audit)
+            level: "info",
+            // Whether or not to include metric events in the log output
+            metrics: false,
+            // Whether or not to include audit events in the log output
+            audit: false
+        }
+    },
+
+    // Customising the editor
+    editorTheme: {
+        projects: {
+            // To enable the Projects feature, set this value to true
+            enabled: false
+        }
+    }
+}
diff --git a/examples/basyx.nodered/package.json b/examples/basyx.nodered/package.json
new file mode 100644
index 0000000..03f658f
--- /dev/null
+++ b/examples/basyx.nodered/package.json
@@ -0,0 +1,35 @@
+{
+    "name": "node-red-docker",
+    "version": "1.1.2",
+    "description": "Low-code programming for event-driven applications",
+    "homepage": "http://nodered.org",
+    "license": "Apache-2.0",
+    "repository": {
+        "type": "git",
+        "url": "https://github.com/node-red/node-red-docker.git"
+    },
+    "main": "node_modules/node-red/red/red.js",
+    "scripts": {
+        "start": "node $NODE_OPTIONS node_modules/node-red/red.js $FLOWS",
+        "debug": "node --inspect=0.0.0.0:9229 $NODE_OPTIONS node_modules/node-red/red.js $FLOWS",
+        "debug_brk": "node --inspect=0.0.0.0:9229 --inspect-brk $NODE_OPTIONS node_modules/node-red/red.js $FLOWS"
+    },
+    "contributors": [
+        {
+            "name": "Dave Conway-Jones"
+        },
+        {
+            "name": "Nick O'Leary"
+        },
+        {
+            "name": "James Thomas"
+        },
+        {                                                                                                                                                                                                "name": "Raymond Mouthaan"                                                                                                                                                               }                                                                                                                                                                                        ],
+    "dependencies": {
+        "node-red": "1.1.2",
+        "node-red-contrib-graphs": "0.3.5"
+    },
+    "engines": {
+        "node": ">=10"
+    }
+}
\ No newline at end of file
diff --git a/examples/basyx.nodered/settings.js b/examples/basyx.nodered/settings.js
new file mode 100644
index 0000000..f3c93f5
--- /dev/null
+++ b/examples/basyx.nodered/settings.js
@@ -0,0 +1,299 @@
+/**
+ * Copyright JS Foundation and other contributors, http://js.foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ **/
+
+module.exports = {
+    // the tcp port that the Node-RED web server is listening on
+    uiPort: process.env.PORT || 1880,
+
+    // By default, the Node-RED UI accepts connections on all IPv4 interfaces.
+    // To listen on all IPv6 addresses, set uiHost to "::",
+    // The following property can be used to listen on a specific interface. For
+    // example, the following would only allow connections from the local machine.
+    //uiHost: "127.0.0.1",
+
+    // Retry time in milliseconds for MQTT connections
+    mqttReconnectTime: 15000,
+
+    // Retry time in milliseconds for Serial port connections
+    serialReconnectTime: 15000,
+
+    // Retry time in milliseconds for TCP socket connections
+    //socketReconnectTime: 10000,
+
+    // Timeout in milliseconds for TCP server socket connections
+    //  defaults to no timeout
+    //socketTimeout: 120000,
+
+    // Maximum number of messages to wait in queue while attempting to connect to TCP socket
+    //  defaults to 1000
+    //tcpMsgQueueSize: 2000,
+
+    // Timeout in milliseconds for HTTP request connections
+    //  defaults to 120 seconds
+    //httpRequestTimeout: 120000,
+
+    // The maximum length, in characters, of any message sent to the debug sidebar tab
+    debugMaxLength: 1000,
+
+    // The maximum number of messages nodes will buffer internally as part of their
+    // operation. This applies across a range of nodes that operate on message sequences.
+    //  defaults to no limit. A value of 0 also means no limit is applied.
+    //nodeMessageBufferMaxLength: 0,
+
+    // To disable the option for using local files for storing keys and certificates in the TLS configuration
+    //  node, set this to true
+    //tlsConfigDisableLocalFiles: true,
+
+    // Colourise the console output of the debug node
+    //debugUseColors: true,
+
+    // The file containing the flows. If not set, it defaults to flows_<hostname>.json
+    //flowFile: 'flows.json',
+
+    // To enabled pretty-printing of the flow within the flow file, set the following
+    //  property to true:
+    //flowFilePretty: true,
+
+    // By default, credentials are encrypted in storage using a generated key. To
+    // specify your own secret, set the following property.
+    // If you want to disable encryption of credentials, set this property to false.
+    // Note: once you set this property, do not change it - doing so will prevent
+    // node-red from being able to decrypt your existing credentials and they will be
+    // lost.
+    //credentialSecret: "a-secret-key",
+
+    // By default, all user data is stored in a directory called `.node-red` under
+    // the user's home directory. To use a different location, the following
+    // property can be used
+    //userDir: '/home/nol/.node-red/',
+
+    // Node-RED scans the `nodes` directory in the userDir to find local node files.
+    // The following property can be used to specify an additional directory to scan.
+    //nodesDir: '/home/nol/.node-red/nodes',
+
+    // By default, the Node-RED UI is available at http://localhost:1880/
+    // The following property can be used to specify a different root path.
+    // If set to false, this is disabled.
+    //httpAdminRoot: '/admin',
+
+    // Some nodes, such as HTTP In, can be used to listen for incoming http requests.
+    // By default, these are served relative to '/'. The following property
+    // can be used to specifiy a different root path. If set to false, this is
+    // disabled.
+    //httpNodeRoot: '/red-nodes',
+
+    // The following property can be used in place of 'httpAdminRoot' and 'httpNodeRoot',
+    // to apply the same root to both parts.
+    //httpRoot: '/red',
+
+    // When httpAdminRoot is used to move the UI to a different root path, the
+    // following property can be used to identify a directory of static content
+    // that should be served at http://localhost:1880/.
+    //httpStatic: '/home/nol/node-red-static/',
+
+    // The maximum size of HTTP request that will be accepted by the runtime api.
+    // Default: 5mb
+    //apiMaxLength: '5mb',
+
+    // If you installed the optional node-red-dashboard you can set it's path
+    // relative to httpRoot
+    //ui: { path: "ui" },
+
+    // Securing Node-RED
+    // -----------------
+    // To password protect the Node-RED editor and admin API, the following
+    // property can be used. See http://nodered.org/docs/security.html for details.
+    //adminAuth: {
+    //    type: "credentials",
+    //    users: [{
+    //        username: "admin",
+    //        password: "$2a$08$zZWtXTja0fB1pzD4sHCMyOCMYz2Z6dNbM6tl8sJogENOMcxWV9DN.",
+    //        permissions: "*"
+    //    }]
+    //},
+
+    // To password protect the node-defined HTTP endpoints (httpNodeRoot), or
+    // the static content (httpStatic), the following properties can be used.
+    // The pass field is a bcrypt hash of the password.
+    // See http://nodered.org/docs/security.html#generating-the-password-hash
+    //httpNodeAuth: {user:"user",pass:"$2a$08$zZWtXTja0fB1pzD4sHCMyOCMYz2Z6dNbM6tl8sJogENOMcxWV9DN."},
+    //httpStaticAuth: {user:"user",pass:"$2a$08$zZWtXTja0fB1pzD4sHCMyOCMYz2Z6dNbM6tl8sJogENOMcxWV9DN."},
+
+    // The following property can be used to enable HTTPS
+    // See http://nodejs.org/api/https.html#https_https_createserver_options_requestlistener
+    // for details on its contents.
+    // This property can be either an object, containing both a (private) key and a (public) certificate,
+    // or a function that returns such an object:
+    //// https object:
+    //https: {
+    //  key: require("fs").readFileSync('privkey.pem'),
+    //  cert: require("fs").readFileSync('cert.pem')
+    //},
+    ////https function:
+    // https: function() {
+    //     // This function should return the options object, or a Promise
+    //     // that resolves to the options object
+    //     return {
+    //         key: require("fs").readFileSync('privkey.pem'),
+    //         cert: require("fs").readFileSync('cert.pem')
+    //     }
+    // },
+
+    // The following property can be used to refresh the https settings at a
+    // regular time interval in hours.
+    // This requires:
+    //   - the `https` setting to be a function that can be called to get
+    //     the refreshed settings.
+    //   - Node.js 11 or later.
+    //httpsRefreshInterval : 12,
+
+    // The following property can be used to cause insecure HTTP connections to
+    // be redirected to HTTPS.
+    //requireHttps: true,
+
+    // The following property can be used to disable the editor. The admin API
+    // is not affected by this option. To disable both the editor and the admin
+    // API, use either the httpRoot or httpAdminRoot properties
+    //disableEditor: false,
+
+    // The following property can be used to configure cross-origin resource sharing
+    // in the HTTP nodes.
+    // See https://github.com/troygoode/node-cors#configuration-options for
+    // details on its contents. The following is a basic permissive set of options:
+    //httpNodeCors: {
+    //    origin: "*",
+    //    methods: "GET,PUT,POST,DELETE"
+    //},
+
+    // If you need to set an http proxy please set an environment variable
+    // called http_proxy (or HTTP_PROXY) outside of Node-RED in the operating system.
+    // For example - http_proxy=http://myproxy.com:8080
+    // (Setting it here will have no effect)
+    // You may also specify no_proxy (or NO_PROXY) to supply a comma separated
+    // list of domains to not proxy, eg - no_proxy=.acme.co,.acme.co.uk
+
+    // The following property can be used to add a custom middleware function
+    // in front of all http in nodes. This allows custom authentication to be
+    // applied to all http in nodes, or any other sort of common request processing.
+    //httpNodeMiddleware: function(req,res,next) {
+    //    // Handle/reject the request, or pass it on to the http in node by calling next();
+    //    // Optionally skip our rawBodyParser by setting this to true;
+    //    //req.skipRawBodyParser = true;
+    //    next();
+    //},
+
+
+    // The following property can be used to add a custom middleware function
+    // in front of all admin http routes. For example, to set custom http
+    // headers
+    // httpAdminMiddleware: function(req,res,next) {
+    //    // Set the X-Frame-Options header to limit where the editor
+    //    // can be embedded
+    //    //res.set('X-Frame-Options', 'sameorigin');
+    //    next();
+    // },
+
+    // The following property can be used to pass custom options to the Express.js
+    // server used by Node-RED. For a full list of available options, refer
+    // to http://expressjs.com/en/api.html#app.settings.table
+    //httpServerOptions: { },
+
+    // The following property can be used to verify websocket connection attempts.
+    // This allows, for example, the HTTP request headers to be checked to ensure
+    // they include valid authentication information.
+    //webSocketNodeVerifyClient: function(info) {
+    //    // 'info' has three properties:
+    //    //   - origin : the value in the Origin header
+    //    //   - req : the HTTP request
+    //    //   - secure : true if req.connection.authorized or req.connection.encrypted is set
+    //    //
+    //    // The function should return true if the connection should be accepted, false otherwise.
+    //    //
+    //    // Alternatively, if this function is defined to accept a second argument, callback,
+    //    // it can be used to verify the client asynchronously.
+    //    // The callback takes three arguments:
+    //    //   - result : boolean, whether to accept the connection or not
+    //    //   - code : if result is false, the HTTP error status to return
+    //    //   - reason: if result is false, the HTTP reason string to return
+    //},
+
+    // The following property can be used to seed Global Context with predefined
+    // values. This allows extra node modules to be made available with the
+    // Function node.
+    // For example,
+    //    functionGlobalContext: { os:require('os') }
+    // can be accessed in a function block as:
+    //    global.get("os")
+    functionGlobalContext: {
+        // os:require('os'),
+        // jfive:require("johnny-five"),
+        // j5board:require("johnny-five").Board({repl:false})
+    },
+    // `global.keys()` returns a list of all properties set in global context.
+    // This allows them to be displayed in the Context Sidebar within the editor.
+    // In some circumstances it is not desirable to expose them to the editor. The
+    // following property can be used to hide any property set in `functionGlobalContext`
+    // from being list by `global.keys()`.
+    // By default, the property is set to false to avoid accidental exposure of
+    // their values. Setting this to true will cause the keys to be listed.
+    exportGlobalContextKeys: false,
+
+
+    // Context Storage
+    // The following property can be used to enable context storage. The configuration
+    // provided here will enable file-based context that flushes to disk every 30 seconds.
+    // Refer to the documentation for further options: https://nodered.org/docs/api/context/
+    //
+    //contextStorage: {
+    //    default: {
+    //        module:"localfilesystem"
+    //    },
+    //},
+
+    // The following property can be used to order the categories in the editor
+    // palette. If a node's category is not in the list, the category will get
+    // added to the end of the palette.
+    // If not set, the following default order is used:
+    //paletteCategories: ['subflows', 'common', 'function', 'network', 'sequence', 'parser', 'storage'],
+
+    // Configure the logging output
+    logging: {
+        // Only console logging is currently supported
+        console: {
+            // Level of logging to be recorded. Options are:
+            // fatal - only those errors which make the application unusable should be recorded
+            // error - record errors which are deemed fatal for a particular request + fatal errors
+            // warn - record problems which are non fatal + errors + fatal errors
+            // info - record information about the general running of the application + warn + error + fatal errors
+            // debug - record information which is more verbose than info + info + warn + error + fatal errors
+            // trace - record very detailed logging + debug + info + warn + error + fatal errors
+            // off - turn off all logging (doesn't affect metrics or audit)
+            level: "info",
+            // Whether or not to include metric events in the log output
+            metrics: false,
+            // Whether or not to include audit events in the log output
+            audit: false
+        }
+    },
+
+    // Customising the editor
+    editorTheme: {
+        projects: {
+            // To enable the Projects feature, set this value to true
+            enabled: false
+        }
+    }
+}
diff --git a/examples/basyx.nodered/start.bat b/examples/basyx.nodered/start.bat
new file mode 100644
index 0000000..83ed0d0
--- /dev/null
+++ b/examples/basyx.nodered/start.bat
@@ -0,0 +1 @@
+docker-compose up
diff --git a/examples/basyx.nodered/start.sh b/examples/basyx.nodered/start.sh
new file mode 100644
index 0000000..d935e43
--- /dev/null
+++ b/examples/basyx.nodered/start.sh
@@ -0,0 +1,2 @@
+#!/usr/bin/env sh
+docker-compose up
\ No newline at end of file
diff --git a/examples/basyx.nodered/stop.bat b/examples/basyx.nodered/stop.bat
new file mode 100644
index 0000000..58694d0
--- /dev/null
+++ b/examples/basyx.nodered/stop.bat
@@ -0,0 +1 @@
+docker-compose down
\ No newline at end of file
diff --git a/examples/basyx.nodered/stop.sh b/examples/basyx.nodered/stop.sh
new file mode 100644
index 0000000..f5139e2
--- /dev/null
+++ b/examples/basyx.nodered/stop.sh
@@ -0,0 +1,2 @@
+#!/usr/bin/env sh
+docker-compose down
\ No newline at end of file
diff --git a/examples/basyx.streamsheets/.gitignore b/examples/basyx.streamsheets/.gitignore
new file mode 100644
index 0000000..5e2ad3c
--- /dev/null
+++ b/examples/basyx.streamsheets/.gitignore
@@ -0,0 +1,2 @@
+/mosquitto
+/streamsheets
\ No newline at end of file
diff --git a/examples/basyx.streamsheets/AAS Property Dashboard.json b/examples/basyx.streamsheets/AAS Property Dashboard.json
new file mode 100644
index 0000000..ecf6f0c
--- /dev/null
+++ b/examples/basyx.streamsheets/AAS Property Dashboard.json
@@ -0,0 +1,5225 @@
+{
+  "machines": [
+    {
+      "machine": {
+        "id": "S1-EB3RpyP",
+        "name": "AAS Property Dashboard",
+        "state": "stopped",
+        "metadata": {
+          "owner": "anon",
+          "lastModified": 1599658322212,
+          "lastModifiedBy": "unknown",
+          "machineservice": {
+            "id": "machines-HkgWO-Rp1v"
+          }
+        },
+        "streamsheets": [
+          {
+            "id": "Sk7ErnRTJD",
+            "name": "S1",
+            "loop": {
+              "path": "",
+              "enabled": false
+            },
+            "inbox": {
+              "max": 20,
+              "type": "MessageBox",
+              "id": "SyENH3Aakw",
+              "stream": null
+            },
+            "sheet": {
+              "cells": {
+                "G1": {
+                  "value": "",
+                  "type": "string",
+                  "level": 0
+                },
+                "A3": {
+                  "formula": "REST.REQUEST(|AASRESTTestProducer,\"http://aas-wrapper:6500/streamsheets/temp\",\"GET\",INBOX(\"dataElement\"))",
+                  "value": "B14q-zULED",
+                  "type": "undefined",
+                  "level": 0,
+                  "references": [
+                    "|AASRESTTestProducer"
+                  ]
+                },
+                "B3": {
+                  "formula": "READ(INBOXDATA(,,\"content\"),,\"Array\")",
+                  "value": "content",
+                  "type": "undefined",
+                  "level": 0
+                },
+                "C3": {
+                  "formula": "READ(INBOXDATA(,,\"timestamp\"),,\"Array\")",
+                  "value": "timestamp",
+                  "type": "undefined",
+                  "level": 0
+                },
+                "G3": {
+                  "value": "Time",
+                  "type": "string",
+                  "level": 0
+                },
+                "H3": {
+                  "value": "Temperature",
+                  "type": "string",
+                  "level": 0
+                },
+                "B4": {
+                  "formula": "READ(INBOXDATA(,,B3,\"0\"),H4,\"Number\")",
+                  "value": 0,
+                  "type": "undefined",
+                  "level": 0
+                },
+                "C4": {
+                  "formula": "READ(INBOXDATA(,,C3,\"0\"),D4,\"String\")",
+                  "value": 0,
+                  "type": "undefined",
+                  "level": 0
+                },
+                "D4": {
+                  "value": "2020-09-09T13:00:40.409Z",
+                  "type": "string",
+                  "level": 0
+                },
+                "G4": {
+                  "formula": "JSONTIME2EXCEL(D4)",
+                  "value": 44083.54213436342,
+                  "type": "undefined",
+                  "level": 0
+                },
+                "H4": {
+                  "value": 21.07154194806827,
+                  "type": "number",
+                  "level": 0
+                },
+                "B5": {
+                  "formula": "READ(INBOXDATA(,,B3,\"1\"),H5,\"Number\")",
+                  "value": 1,
+                  "type": "undefined",
+                  "level": 0
+                },
+                "C5": {
+                  "formula": "READ(INBOXDATA(,,C3,\"1\"),D5,\"String\")",
+                  "value": 1,
+                  "type": "undefined",
+                  "level": 0
+                },
+                "D5": {
+                  "value": "2020-09-09T13:00:41.415Z",
+                  "type": "string",
+                  "level": 0
+                },
+                "G5": {
+                  "formula": "JSONTIME2EXCEL(D5)",
+                  "value": 44083.54213436342,
+                  "type": "undefined",
+                  "level": 0
+                },
+                "H5": {
+                  "value": 28.496771926635027,
+                  "type": "number",
+                  "level": 0
+                },
+                "B6": {
+                  "formula": "READ(INBOXDATA(,,B3,\"2\"),H6,\"Number\")",
+                  "value": 2,
+                  "type": "undefined",
+                  "level": 0
+                },
+                "C6": {
+                  "formula": "READ(INBOXDATA(,,C3,\"2\"),D6,\"String\")",
+                  "value": 2,
+                  "type": "undefined",
+                  "level": 0
+                },
+                "D6": {
+                  "value": "2020-09-09T13:00:42.422Z",
+                  "type": "string",
+                  "level": 0
+                },
+                "G6": {
+                  "formula": "JSONTIME2EXCEL(D6)",
+                  "value": 44083.54213436342,
+                  "type": "undefined",
+                  "level": 0
+                },
+                "H6": {
+                  "value": 27.348393994685246,
+                  "type": "number",
+                  "level": 0
+                },
+                "B7": {
+                  "formula": "READ(INBOXDATA(,,B3,\"3\"),H7,\"Number\")",
+                  "value": 3,
+                  "type": "undefined",
+                  "level": 0
+                },
+                "C7": {
+                  "formula": "READ(INBOXDATA(,,C3,\"3\"),D7,\"String\")",
+                  "value": 3,
+                  "type": "undefined",
+                  "level": 0
+                },
+                "D7": {
+                  "value": "2020-09-09T13:00:43.427Z",
+                  "type": "string",
+                  "level": 0
+                },
+                "G7": {
+                  "formula": "JSONTIME2EXCEL(D7)",
+                  "value": 44083.54213436342,
+                  "type": "undefined",
+                  "level": 0
+                },
+                "H7": {
+                  "value": 21.369693237856616,
+                  "type": "number",
+                  "level": 0
+                },
+                "B8": {
+                  "formula": "READ(INBOXDATA(,,B3,\"4\"),H8,\"Number\")",
+                  "value": 4,
+                  "type": "undefined",
+                  "level": 0
+                },
+                "C8": {
+                  "formula": "READ(INBOXDATA(,,C3,\"4\"),D8,\"String\")",
+                  "value": 4,
+                  "type": "undefined",
+                  "level": 0
+                },
+                "D8": {
+                  "value": "2020-09-09T13:00:44.436Z",
+                  "type": "string",
+                  "level": 0
+                },
+                "G8": {
+                  "formula": "JSONTIME2EXCEL(D8)",
+                  "value": 44083.54213436342,
+                  "type": "undefined",
+                  "level": 0
+                },
+                "H8": {
+                  "value": 24.00643356528727,
+                  "type": "number",
+                  "level": 0
+                },
+                "B9": {
+                  "formula": "READ(INBOXDATA(,,B3,\"5\"),H9,\"Number\")",
+                  "value": 5,
+                  "type": "undefined",
+                  "level": 0
+                },
+                "C9": {
+                  "formula": "READ(INBOXDATA(,,C3,\"5\"),D9,\"String\")",
+                  "value": 5,
+                  "type": "undefined",
+                  "level": 0
+                },
+                "D9": {
+                  "value": "2020-09-09T13:00:45.443Z",
+                  "type": "string",
+                  "level": 0
+                },
+                "G9": {
+                  "formula": "JSONTIME2EXCEL(D9)",
+                  "value": 44083.54213436342,
+                  "type": "undefined",
+                  "level": 0
+                },
+                "H9": {
+                  "value": 29.263190638856287,
+                  "type": "number",
+                  "level": 0
+                },
+                "B10": {
+                  "formula": "READ(INBOXDATA(,,B3,\"6\"),H10,\"Number\")",
+                  "value": 6,
+                  "type": "undefined",
+                  "level": 0
+                },
+                "C10": {
+                  "formula": "READ(INBOXDATA(,,C3,\"6\"),D10,\"String\")",
+                  "value": 6,
+                  "type": "undefined",
+                  "level": 0
+                },
+                "D10": {
+                  "value": "2020-09-09T13:00:46.449Z",
+                  "type": "string",
+                  "level": 0
+                },
+                "G10": {
+                  "formula": "JSONTIME2EXCEL(D10)",
+                  "value": 44083.54213436342,
+                  "type": "undefined",
+                  "level": 0
+                },
+                "H10": {
+                  "value": 20.655619621525332,
+                  "type": "number",
+                  "level": 0
+                },
+                "B11": {
+                  "formula": "READ(INBOXDATA(,,B3,\"7\"),H11,\"Number\")",
+                  "value": 7,
+                  "type": "undefined",
+                  "level": 0
+                },
+                "C11": {
+                  "formula": "READ(INBOXDATA(,,C3,\"7\"),D11,\"String\")",
+                  "value": 7,
+                  "type": "undefined",
+                  "level": 0
+                },
+                "D11": {
+                  "value": "2020-09-09T13:00:47.454Z",
+                  "type": "string",
+                  "level": 0
+                },
+                "G11": {
+                  "formula": "JSONTIME2EXCEL(D11)",
+                  "value": 44083.54213436342,
+                  "type": "undefined",
+                  "level": 0
+                },
+                "H11": {
+                  "value": 27.183770324976013,
+                  "type": "number",
+                  "level": 0
+                },
+                "B12": {
+                  "formula": "READ(INBOXDATA(,,B3,\"8\"),H12,\"Number\")",
+                  "value": 8,
+                  "type": "undefined",
+                  "level": 0
+                },
+                "C12": {
+                  "formula": "READ(INBOXDATA(,,C3,\"8\"),D12,\"String\")",
+                  "value": 8,
+                  "type": "undefined",
+                  "level": 0
+                },
+                "D12": {
+                  "value": "2020-09-09T13:00:48.464Z",
+                  "type": "string",
+                  "level": 0
+                },
+                "G12": {
+                  "formula": "JSONTIME2EXCEL(D12)",
+                  "value": 44083.54213436342,
+                  "type": "undefined",
+                  "level": 0
+                },
+                "H12": {
+                  "value": 25.686867950571894,
+                  "type": "number",
+                  "level": 0
+                },
+                "B13": {
+                  "formula": "READ(INBOXDATA(,,B3,\"9\"),H13,\"Number\")",
+                  "value": 9,
+                  "type": "undefined",
+                  "level": 0
+                },
+                "C13": {
+                  "formula": "READ(INBOXDATA(,,C3,\"9\"),D13,\"String\")",
+                  "value": 9,
+                  "type": "undefined",
+                  "level": 0
+                },
+                "D13": {
+                  "value": "2020-09-09T13:00:49.469Z",
+                  "type": "string",
+                  "level": 0
+                },
+                "G13": {
+                  "formula": "JSONTIME2EXCEL(D13)",
+                  "value": 44083.54213436342,
+                  "type": "undefined",
+                  "level": 0
+                },
+                "H13": {
+                  "value": 20.187588152170466,
+                  "type": "number",
+                  "level": 0
+                },
+                "F24": {
+                  "value": "",
+                  "type": "string",
+                  "level": 0
+                },
+                "F4": {
+                  "value": 1,
+                  "type": "number",
+                  "level": 0
+                },
+                "F5": {
+                  "value": 2,
+                  "type": "number",
+                  "level": 0
+                },
+                "F6": {
+                  "value": 3,
+                  "type": "number",
+                  "level": 0
+                },
+                "F7": {
+                  "value": 4,
+                  "type": "number",
+                  "level": 0
+                },
+                "F8": {
+                  "value": 5,
+                  "type": "number",
+                  "level": 0
+                },
+                "F9": {
+                  "value": 6,
+                  "type": "number",
+                  "level": 0
+                },
+                "F10": {
+                  "value": 7,
+                  "type": "number",
+                  "level": 0
+                },
+                "F11": {
+                  "value": 8,
+                  "type": "number",
+                  "level": 0
+                },
+                "F12": {
+                  "value": 9,
+                  "type": "number",
+                  "level": 0
+                },
+                "F13": {
+                  "value": 10,
+                  "type": "number",
+                  "level": 0
+                },
+                "H18": {
+                  "value": "Temperature Sensor",
+                  "type": "string",
+                  "level": 0
+                }
+              },
+              "namedCells": {},
+              "graphCells": {
+                "70847796661": {
+                  "formula": "DRAW.POLYGON(\"70847796661\",,\"Polygon1\",12289,2675,18415,3493,,\"#345678\")",
+                  "type": "string",
+                  "value": "#CALC"
+                },
+                "555401109981": {
+                  "formula": "DRAW.CHART(\"555401109981\",,\"Chart1\",15262,7480,8149,5080,,,,,,,\"column\",S1!G4:H13)",
+                  "type": "string",
+                  "value": "#CALC"
+                },
+                "60201705755": {
+                  "formula": "DRAW.RECTANGLE(\"60201705755\",,\"Rectangle9\",12355,2700,7091,1984,\"None\",FILLPATTERN(\"https://www.basys40.de/wp-content/uploads/2019/12/Logo_BaSys4_1024px-300x79.png\"))",
+                  "type": "string",
+                  "value": "#CALC"
+                },
+                "488440667154": {
+                  "formula": "DRAW.RECTANGLE(\"488440667154\",,\"Rectangle10\",3967,9421,1773,10001,,\"#345678\")",
+                  "type": "string",
+                  "value": "#CALC"
+                },
+                "919991966926": {
+                  "formula": "DRAW.RECTANGLE(\"919991966926\",,\"Rectangle11\",20623,9433,1746,10001,,\"#345678\")",
+                  "type": "string",
+                  "value": "#CALC"
+                },
+                "962757771226": {
+                  "formula": "DRAW.RECTANGLE(\"962757771226\",,\"Rectangle12\",12302,11081,14896,1376,,\"#345678\")",
+                  "type": "string",
+                  "value": "#CALC"
+                },
+                "692699117567": {
+                  "formula": "DRAW.BEZIER(\"692699117567\",,\"Bezier1\",17647,13394,212,1164)",
+                  "type": "boolean",
+                  "value": true
+                },
+                "426951475952": {
+                  "formula": "DRAW.ELLIPSE(\"426951475952\",\"Bezier1\",\"Ellipse1\",106,1032,529,529,,\"#ff0000\")",
+                  "type": "string",
+                  "value": "#CALC"
+                }
+              },
+              "properties": {
+                "sheet": {},
+                "cols": {},
+                "rows": {},
+                "cells": {}
+              },
+              "settings": {
+                "minrow": 1,
+                "maxrow": 100,
+                "mincol": -2,
+                "maxcol": 50,
+                "protected": false
+              },
+              "drawings": {},
+              "graphItems": {}
+            },
+            "trigger": {
+              "type": "start",
+              "repeat": "endless"
+            }
+          }
+        ],
+        "settings": {
+          "locale": "en",
+          "isOPCUA": false,
+          "cycletime": 200
+        },
+        "className": "Machine",
+        "namedCells": {
+          "|AASRESTTestProducer": {
+            "value": {
+              "id": "HJZR0U1xSI",
+              "name": "AASRESTTestProducer",
+              "type": "producer",
+              "state": "connected",
+              "timestamp": 1599656146504
+            },
+            "type": "object",
+            "info": {},
+            "level": 0
+          },
+          "|MQTT_Consumer": {
+            "value": {
+              "id": "CONSUMER_MQTT",
+              "name": "MQTT_Consumer",
+              "type": "stream",
+              "state": "disconnected",
+              "timestamp": 1599656156501
+            },
+            "type": "object",
+            "info": {},
+            "level": 0
+          },
+          "|Wind_Data": {
+            "value": {
+              "id": "HkZRIJtchH",
+              "name": "Wind_Data",
+              "type": "stream",
+              "state": "disconnected",
+              "timestamp": 1599656156513
+            },
+            "type": "object",
+            "info": {},
+            "level": 0
+          },
+          "|MQTT_Producer": {
+            "value": {
+              "id": "PRODUCER_MQTT",
+              "name": "MQTT_Producer",
+              "type": "producer",
+              "state": "disconnected",
+              "timestamp": 1599656156514
+            },
+            "type": "object",
+            "info": {},
+            "level": 0
+          },
+          "|SMTP_Sender": {
+            "value": {
+              "id": "B1-zoM0x1v",
+              "name": "SMTP_Sender",
+              "type": "producer",
+              "state": "disconnected",
+              "timestamp": 1599656167573
+            },
+            "type": "object",
+            "info": {},
+            "level": 0
+          }
+        },
+        "defproperties": {
+          "attributes": {
+            "cell": {
+              "level": 0,
+              "protected": true,
+              "visible": true,
+              "key": false
+            },
+            "sheet": {
+              "defaultsectionsize": 2000,
+              "initialsection": 0
+            }
+          },
+          "formats": {
+            "styles": {
+              "brightness": 0,
+              "fillstyle": 0,
+              "fillcolor": "#FFFFFF",
+              "gradientcolor": "#CCCCCC",
+              "gradientcolorstops": "",
+              "gradientangle": 0,
+              "gradienttype": 0,
+              "gradientoffset_x": 0,
+              "gradientoffset_y": 0,
+              "linecolor": "#000000",
+              "linewidth": -1,
+              "linestyle": 1,
+              "lineshape": 0,
+              "linetransparency": 100,
+              "pattern": "",
+              "patternstyle": 0,
+              "transparency": 100,
+              "leftbordercolor": "#000000",
+              "leftborderstyle": 0,
+              "leftborderwidth": 1,
+              "topbordercolor": "#000000",
+              "topborderstyle": 0,
+              "topborderwidth": 1,
+              "rightbordercolor": "#000000",
+              "rightborderstyle": 0,
+              "rightborderwidth": 1,
+              "bottombordercolor": "#000000",
+              "bottomborderstyle": 0,
+              "bottomborderwidth": 1
+            },
+            "text": {
+              "baseline": "alphabetic",
+              "valign": 2,
+              "halign": 3,
+              "fontsize": 9,
+              "fontname": "Verdana",
+              "fontcolor": "#000000",
+              "fontstyle": 0,
+              "vposition": 3,
+              "hpostion": 3,
+              "richtext": true,
+              "lineheight": 1.2,
+              "numberformat": "General",
+              "localculture": "general"
+            }
+          }
+        }
+      },
+      "graph": {
+        "id": "SkHS206JD",
+        "graphdef": {
+          "type": "machinegraph",
+          "version": "2",
+          "uniqueid": "1",
+          "o-outbox": {
+            "split": "5000",
+            "width": "5000"
+          },
+          "a-graphitem": [
+            {
+              "id": "1000",
+              "o-attributes": {
+                "o-sheetid": {
+                  "v": "Sk7ErnRTJD",
+                  "t": "s"
+                }
+              },
+              "o-pin": {
+                "o-p": {
+                  "o-x": {
+                    "v": "16933"
+                  },
+                  "o-y": {
+                    "v": "7814"
+                  }
+                },
+                "o-lp": {
+                  "o-x": {
+                    "f": "WIDTH%20*%200.5",
+                    "v": "16433"
+                  },
+                  "o-y": {
+                    "f": "HEIGHT%20*%200.5",
+                    "v": "7314"
+                  }
+                }
+              },
+              "o-size": {
+                "o-w": {
+                  "v": "32867"
+                },
+                "o-h": {
+                  "v": "14628"
+                }
+              },
+              "o-inbox": {
+                "split": "5000",
+                "width": "6111"
+              },
+              "o-processsheet": {
+                "o-attributes": {
+                  "o-calcondemand": {
+                    "v": "true",
+                    "t": "b"
+                  }
+                },
+                "o-name": {
+                  "v": "S1",
+                  "t": "s"
+                },
+                "o-rows": {
+                  "a-section": [
+                    {
+                      "index": "0",
+                      "size": "2140",
+                      "visible": "1"
+                    },
+                    {
+                      "index": "1",
+                      "size": "2458",
+                      "visible": "1"
+                    },
+                    {
+                      "index": "2",
+                      "size": "632",
+                      "visible": "1"
+                    },
+                    {
+                      "index": "15",
+                      "size": "1003",
+                      "visible": "1"
+                    },
+                    {
+                      "index": "16",
+                      "size": "738",
+                      "visible": "1"
+                    },
+                    {
+                      "index": "17",
+                      "size": "738",
+                      "visible": "1"
+                    },
+                    {
+                      "index": "18",
+                      "size": "1161",
+                      "visible": "1"
+                    }
+                  ]
+                },
+                "o-columns": {
+                  "a-section": [
+                    {
+                      "index": "0",
+                      "size": "0",
+                      "visible": "0"
+                    },
+                    {
+                      "index": "1",
+                      "size": "515",
+                      "visible": "1"
+                    },
+                    {
+                      "index": "2",
+                      "size": "0",
+                      "visible": "0"
+                    },
+                    {
+                      "index": "3",
+                      "size": "0",
+                      "visible": "0"
+                    },
+                    {
+                      "index": "4",
+                      "size": "0",
+                      "visible": "0"
+                    },
+                    {
+                      "index": "5",
+                      "size": "0",
+                      "visible": "0"
+                    },
+                    {
+                      "index": "6",
+                      "size": "4175",
+                      "visible": "1"
+                    },
+                    {
+                      "index": "7",
+                      "size": "1086",
+                      "visible": "1"
+                    },
+                    {
+                      "index": "8",
+                      "size": "1921",
+                      "visible": "1"
+                    },
+                    {
+                      "index": "9",
+                      "size": "3561",
+                      "visible": "1"
+                    },
+                    {
+                      "index": "13",
+                      "size": "1418",
+                      "visible": "1"
+                    }
+                  ]
+                },
+                "o-drawings": {
+                  "a-graphitem": [
+                    {
+                      "id": "70847796661",
+                      "parentid": "1028",
+                      "o-al": {
+                        "n": "model.attributes",
+                        "cl": "JSG.AttributeList",
+                        "a-al": [
+                          {
+                            "n": "format",
+                            "cl": "FormatAttributes",
+                            "a-al": [
+                              {
+                                "n": "fillcolor",
+                                "o-vl": {
+                                  "v": "%23345678",
+                                  "t": "s"
+                                }
+                              }
+                            ]
+                          },
+                          {
+                            "n": "graphitem",
+                            "cl": "ItemAttributes",
+                            "a-al": [
+                              {
+                                "n": "sheetformula",
+                                "o-vl": {
+                                  "f": "DRAW.POLYGON(~2270847796661~22%2C%2C~22Polygon1~22%2C12289%2C2675%2C18415%2C3493%2C%2C~22%23345678~22)",
+                                  "v": "0"
+                                }
+                              },
+                              {
+                                "n": "sheetsource",
+                                "cl": "StringAttribute",
+                                "o-vl": {
+                                  "v": "name",
+                                  "t": "s"
+                                }
+                              }
+                            ]
+                          }
+                        ]
+                      },
+                      "o-type": {
+                        "v": "rectCornerCutSame",
+                        "t": "s"
+                      },
+                      "o-name": {
+                        "v": "Polygon1",
+                        "t": "s"
+                      },
+                      "o-pin": {
+                        "o-p": {
+                          "o-x": {
+                            "v": "12289"
+                          },
+                          "o-y": {
+                            "v": "2675"
+                          }
+                        },
+                        "o-lp": {
+                          "o-x": {
+                            "f": "WIDTH%20*%200.5",
+                            "v": "9208"
+                          },
+                          "o-y": {
+                            "f": "HEIGHT%20*%200.5",
+                            "v": "1746"
+                          }
+                        }
+                      },
+                      "o-size": {
+                        "o-w": {
+                          "v": "18415"
+                        },
+                        "o-h": {
+                          "v": "3493"
+                        }
+                      },
+                      "o-rscoordinates": {
+                        "a-c": [
+                          {
+                            "name": "CUTTOP",
+                            "xtype": "13",
+                            "ytype": "-1",
+                            "xMax": "0.5",
+                            "o-x": {
+                              "v": "0.10"
+                            },
+                            "o-y": {
+                              "v": "0.00"
+                            }
+                          },
+                          {
+                            "name": "CUTBOTTOM",
+                            "xtype": "13",
+                            "ytype": "-1",
+                            "xMax": "0.5",
+                            "yMin": "1",
+                            "yMax": "1",
+                            "o-x": {
+                              "v": "0.00"
+                            },
+                            "o-y": {
+                              "v": "1.00"
+                            }
+                          }
+                        ]
+                      },
+                      "o-shape": {
+                        "type": "polygon",
+                        "o-cs": {
+                          "a-c": [
+                            {
+                              "o-x": {
+                                "f": "MIN(WIDTH%2C%20HEIGHT)%20*%20CUTTOP",
+                                "v": "0"
+                              },
+                              "o-y": {
+                                "v": "0"
+                              }
+                            },
+                            {
+                              "o-x": {
+                                "v": "0"
+                              },
+                              "o-y": {
+                                "f": "MIN(WIDTH%2C%20HEIGHT)%20*%20CUTTOP",
+                                "v": "0"
+                              }
+                            },
+                            {
+                              "o-x": {
+                                "v": "0"
+                              },
+                              "o-y": {
+                                "f": "HEIGHT%20-%20MIN(WIDTH%2C%20HEIGHT)%20*%20CUTBOTTOM",
+                                "v": "0"
+                              }
+                            },
+                            {
+                              "o-x": {
+                                "f": "MIN(WIDTH%2C%20HEIGHT)%20*%20CUTBOTTOM",
+                                "v": "0"
+                              },
+                              "o-y": {
+                                "f": "HEIGHT",
+                                "v": "3493"
+                              }
+                            },
+                            {
+                              "o-x": {
+                                "f": "WIDTH%20-%20MIN(WIDTH%2C%20HEIGHT)%20*%20CUTBOTTOM",
+                                "v": "0"
+                              },
+                              "o-y": {
+                                "f": "HEIGHT",
+                                "v": "3493"
+                              }
+                            },
+                            {
+                              "o-x": {
+                                "f": "WIDTH",
+                                "v": "18415"
+                              },
+                              "o-y": {
+                                "f": "HEIGHT%20-%20MIN(WIDTH%2C%20HEIGHT)%20*%20CUTBOTTOM",
+                                "v": "0"
+                              }
+                            },
+                            {
+                              "o-x": {
+                                "f": "WIDTH",
+                                "v": "18415"
+                              },
+                              "o-y": {
+                                "f": "MIN(WIDTH%2C%20HEIGHT)%20*%20CUTTOP",
+                                "v": "0"
+                              }
+                            },
+                            {
+                              "o-x": {
+                                "f": "WIDTH%20-%20MIN(WIDTH%2C%20HEIGHT)%20*%20CUTTOP",
+                                "v": "0"
+                              },
+                              "o-y": {
+                                "v": "0"
+                              }
+                            }
+                          ]
+                        }
+                      },
+                      "type": "node"
+                    },
+                    {
+                      "id": "555401109981",
+                      "parentid": "1028",
+                      "o-al": {
+                        "n": "model.attributes",
+                        "cl": "JSG.AttributeList",
+                        "a-al": [
+                          {
+                            "n": "graphitem",
+                            "cl": "ItemAttributes",
+                            "a-al": [
+                              {
+                                "n": "portmode",
+                                "o-vl": {
+                                  "v": "0"
+                                }
+                              },
+                              {
+                                "n": "sheetformula",
+                                "o-vl": {
+                                  "f": "DRAW.CHART(~22555401109981~22%2C%2C~22Chart1~22%2C15262%2C7480%2C8149%2C5080%2C%2C%2C%2C%2C%2C%2C~22column~22%2CS1!G4%3AH13)",
+                                  "v": "0"
+                                }
+                              },
+                              {
+                                "n": "sheetsource",
+                                "cl": "StringAttribute",
+                                "o-vl": {
+                                  "v": "name",
+                                  "t": "s"
+                                }
+                              }
+                            ]
+                          }
+                        ]
+                      },
+                      "o-name": {
+                        "v": "Chart1",
+                        "t": "s"
+                      },
+                      "o-pin": {
+                        "o-p": {
+                          "o-x": {
+                            "v": "15262"
+                          },
+                          "o-y": {
+                            "v": "7480"
+                          }
+                        },
+                        "o-lp": {
+                          "o-x": {
+                            "f": "WIDTH%20*%200.5",
+                            "v": "4074"
+                          },
+                          "o-y": {
+                            "f": "HEIGHT%20*%200.5",
+                            "v": "2540"
+                          }
+                        }
+                      },
+                      "o-size": {
+                        "o-w": {
+                          "v": "8149"
+                        },
+                        "o-h": {
+                          "v": "5080"
+                        }
+                      },
+                      "o-shape": {
+                        "type": "rectangle"
+                      },
+                      "type": "chartnode",
+                      "data": "{&quot;chartType&quot;:&quot;column&quot;,&quot;coherent&quot;:true,&quot;hasCategoryLabels&quot;:&quot;first&quot;,&quot;hasSeriesLabels&quot;:&quot;first&quot;,&quot;categoryLabelData&quot;:[&quot; 14:46:20 GM&quot;,&quot; 14:46:21 GM&quot;,&quot; 14:46:22 GM&quot;,&quot; 14:46:23 GM&quot;,&quot; 14:46:24 GM&quot;,&quot; 14:46:25 GM&quot;,&quot; 14:46:26 GM&quot;,&quot; 14:46:27 GM&quot;,&quot; 14:46:28 GM&quot;,&quot; 14:46:29 GM&quot;],&quot;direction&quot;:&quot;columns&quot;,&quot;range&quot;:&quot;=S1!G4:H13&quot;,&quot;formatRange&quot;:&quot;&quot;,&quot;categoryRange&quot;:&quot;=E5:E14&quot;,&quot;stacked&quot;:false,&quot;smooth&quot;:true,&quot;step&quot;:false,&quot;fill&quot;:false,&quot;hideEmpty&quot;:&quot;none&quot;,&quot;angle&quot;:6.283185307179586,&quot;series&quot;:[{&quot;categoryLabels&quot;:&quot;=E5:E14&quot;,&quot;seriesLabelRange&quot;:&quot;=F4&quot;,&quot;data&quot;:&quot;=F5:F14&quot;,&quot;seriesLabel&quot;:&quot;Temperature&quot;,&quot;fillColor&quot;:&quot;#4a90e2&quot;,&quot;lineColor&quot;:&quot;#4a90e2&quot;}]}",
+                      "title": "{&quot;title&quot;:&quot;&quot;,&quot;font&quot;:{&quot;fontName&quot;:&quot;Verdana&quot;,&quot;fontSize&quot;:&quot;12&quot;,&quot;bold&quot;:false,&quot;italic&quot;:false,&quot;color&quot;:&quot;#000000&quot;}}",
+                      "legend": "{&quot;position&quot;:&quot;top&quot;,&quot;font&quot;:{&quot;fontName&quot;:&quot;Verdana&quot;,&quot;fontSize&quot;:&quot;7&quot;,&quot;bold&quot;:false,&quot;italic&quot;:false,&quot;color&quot;:&quot;#000000&quot;}}",
+                      "scales": "{&quot;xAxes&quot;:[{&quot;id&quot;:&quot;XAxis1&quot;,&quot;ticks&quot;:{&quot;fontFamily&quot;:&quot;Verdana&quot;,&quot;fontSize&quot;:&quot;7&quot;,&quot;fontColor&quot;:&quot;#000000&quot;,&quot;fontStyle&quot;:&quot;normal&quot;,&quot;minRotation&quot;:0,&quot;maxRotation&quot;:90,&quot;reverse&quot;:false},&quot;gridLines&quot;:{&quot;display&quot;:false,&quot;color&quot;:&quot;#DDDDDD&quot;},&quot;stacked&quot;:false,&quot;type&quot;:&quot;category&quot;,&quot;position&quot;:&quot;bottom&quot;,&quot;scaleLabel&quot;:{&quot;labelString&quot;:&quot;Time&quot;,&quot;display&quot;:true}}],&quot;yAxes&quot;:[{&quot;id&quot;:&quot;YAxis1&quot;,&quot;ticks&quot;:{&quot;fontFamily&quot;:&quot;Verdana&quot;,&quot;fontSize&quot;:&quot;7&quot;,&quot;fontColor&quot;:&quot;#000000&quot;,&quot;fontStyle&quot;:&quot;bold&quot;,&quot;minRotation&quot;:0,&quot;maxRotation&quot;:90,&quot;reverse&quot;:false,&quot;min&quot;:20},&quot;gridLines&quot;:{&quot;display&quot;:true,&quot;color&quot;:&quot;#DDDDDD&quot;},&quot;stacked&quot;:false,&quot;type&quot;:&quot;linear&quot;,&quot;position&quot;:&quot;left&quot;,&quot;scaleLabel&quot;:{&quot;labelString&quot;:&quot;Temperature (ºC)&quot;,&quot;display&quot;:true}}]}"
+                    },
+                    {
+                      "id": "60201705755",
+                      "parentid": "1028",
+                      "o-al": {
+                        "n": "model.attributes",
+                        "cl": "JSG.AttributeList",
+                        "a-al": [
+                          {
+                            "n": "format",
+                            "cl": "FormatAttributes",
+                            "a-al": [
+                              {
+                                "n": "fillstyle",
+                                "o-vl": {
+                                  "v": "3"
+                                }
+                              },
+                              {
+                                "n": "linecolor",
+                                "o-vl": {
+                                  "v": "None",
+                                  "t": "s"
+                                }
+                              },
+                              {
+                                "n": "linestyle",
+                                "o-vl": {
+                                  "v": "0"
+                                }
+                              }
+                            ]
+                          },
+                          {
+                            "n": "graphitem",
+                            "cl": "ItemAttributes",
+                            "a-al": [
+                              {
+                                "n": "sheetformula",
+                                "o-vl": {
+                                  "f": "DRAW.RECTANGLE(~2260201705755~22%2C%2C~22Rectangle9~22%2C12355%2C2700%2C7091%2C1984%2C~22None~22%2CFILLPATTERN(~22https%3A%2F%2Fwww.basys40.de%2Fwp-content%2Fuploads%2F2019%2F12%2FLogo_BaSys4_1024px-300x79.png~22))",
+                                  "v": "0"
+                                }
+                              },
+                              {
+                                "n": "sheetsource",
+                                "cl": "StringAttribute",
+                                "o-vl": {
+                                  "v": "name",
+                                  "t": "s"
+                                }
+                              }
+                            ]
+                          }
+                        ]
+                      },
+                      "o-name": {
+                        "v": "Rectangle9",
+                        "t": "s"
+                      },
+                      "o-pin": {
+                        "o-p": {
+                          "o-x": {
+                            "v": "12355"
+                          },
+                          "o-y": {
+                            "v": "2700"
+                          }
+                        },
+                        "o-lp": {
+                          "o-x": {
+                            "f": "WIDTH%20*%200.5",
+                            "v": "3545"
+                          },
+                          "o-y": {
+                            "f": "HEIGHT%20*%200.5",
+                            "v": "992"
+                          }
+                        }
+                      },
+                      "o-size": {
+                        "o-w": {
+                          "v": "7091"
+                        },
+                        "o-h": {
+                          "v": "1984"
+                        }
+                      },
+                      "o-shape": {
+                        "type": "rectangle"
+                      },
+                      "type": "node"
+                    },
+                    {
+                      "id": "488440667154",
+                      "parentid": "1028",
+                      "o-al": {
+                        "n": "model.attributes",
+                        "cl": "JSG.AttributeList",
+                        "a-al": [
+                          {
+                            "n": "format",
+                            "cl": "FormatAttributes",
+                            "a-al": [
+                              {
+                                "n": "fillcolor",
+                                "o-vl": {
+                                  "v": "%23345678",
+                                  "t": "s"
+                                }
+                              }
+                            ]
+                          },
+                          {
+                            "n": "graphitem",
+                            "cl": "ItemAttributes",
+                            "a-al": [
+                              {
+                                "n": "sheetformula",
+                                "o-vl": {
+                                  "f": "DRAW.RECTANGLE(~22488440667154~22%2C%2C~22Rectangle10~22%2C3967%2C9421%2C1773%2C10001%2C%2C~22%23345678~22)",
+                                  "v": "0"
+                                }
+                              },
+                              {
+                                "n": "sheetsource",
+                                "cl": "StringAttribute",
+                                "o-vl": {
+                                  "v": "name",
+                                  "t": "s"
+                                }
+                              }
+                            ]
+                          }
+                        ]
+                      },
+                      "o-name": {
+                        "v": "Rectangle10",
+                        "t": "s"
+                      },
+                      "o-pin": {
+                        "o-p": {
+                          "o-x": {
+                            "v": "3967"
+                          },
+                          "o-y": {
+                            "v": "9421"
+                          }
+                        },
+                        "o-lp": {
+                          "o-x": {
+                            "f": "WIDTH%20*%200.5",
+                            "v": "886"
+                          },
+                          "o-y": {
+                            "f": "HEIGHT%20*%200.5",
+                            "v": "5001"
+                          }
+                        }
+                      },
+                      "o-size": {
+                        "o-w": {
+                          "v": "1773"
+                        },
+                        "o-h": {
+                          "v": "10001"
+                        }
+                      },
+                      "o-shape": {
+                        "type": "rectangle"
+                      },
+                      "type": "node"
+                    },
+                    {
+                      "id": "919991966926",
+                      "parentid": "1028",
+                      "o-al": {
+                        "n": "model.attributes",
+                        "cl": "JSG.AttributeList",
+                        "a-al": [
+                          {
+                            "n": "format",
+                            "cl": "FormatAttributes",
+                            "a-al": [
+                              {
+                                "n": "fillcolor",
+                                "o-vl": {
+                                  "v": "%23345678",
+                                  "t": "s"
+                                }
+                              }
+                            ]
+                          },
+                          {
+                            "n": "graphitem",
+                            "cl": "ItemAttributes",
+                            "a-al": [
+                              {
+                                "n": "sheetformula",
+                                "o-vl": {
+                                  "f": "DRAW.RECTANGLE(~22919991966926~22%2C%2C~22Rectangle11~22%2C20623%2C9433%2C1746%2C10001%2C%2C~22%23345678~22)",
+                                  "v": "0"
+                                }
+                              },
+                              {
+                                "n": "sheetsource",
+                                "cl": "StringAttribute",
+                                "o-vl": {
+                                  "v": "name",
+                                  "t": "s"
+                                }
+                              }
+                            ]
+                          },
+                          {
+                            "n": "textformat",
+                            "cl": "TextFormatAttributes",
+                            "pl": "tl:TextFormatAttributes.Template",
+                            "a-al": [
+                              {
+                                "n": "richtext",
+                                "o-vl": {
+                                  "v": "false",
+                                  "t": "b"
+                                }
+                              }
+                            ]
+                          }
+                        ]
+                      },
+                      "o-name": {
+                        "v": "Rectangle11",
+                        "t": "s"
+                      },
+                      "o-pin": {
+                        "o-p": {
+                          "o-x": {
+                            "v": "20623"
+                          },
+                          "o-y": {
+                            "v": "9433"
+                          }
+                        },
+                        "o-lp": {
+                          "o-x": {
+                            "f": "WIDTH%20*%200.5",
+                            "v": "873"
+                          },
+                          "o-y": {
+                            "f": "HEIGHT%20*%200.5",
+                            "v": "5001"
+                          }
+                        }
+                      },
+                      "o-size": {
+                        "o-w": {
+                          "v": "1746"
+                        },
+                        "o-h": {
+                          "v": "10001"
+                        }
+                      },
+                      "o-shape": {
+                        "type": "rectangle"
+                      },
+                      "type": "node"
+                    },
+                    {
+                      "id": "962757771226",
+                      "parentid": "1028",
+                      "o-al": {
+                        "n": "model.attributes",
+                        "cl": "JSG.AttributeList",
+                        "a-al": [
+                          {
+                            "n": "format",
+                            "cl": "FormatAttributes",
+                            "a-al": [
+                              {
+                                "n": "fillcolor",
+                                "o-vl": {
+                                  "v": "%23345678",
+                                  "t": "s"
+                                }
+                              }
+                            ]
+                          },
+                          {
+                            "n": "graphitem",
+                            "cl": "ItemAttributes",
+                            "a-al": [
+                              {
+                                "n": "sheetformula",
+                                "o-vl": {
+                                  "f": "DRAW.RECTANGLE(~22962757771226~22%2C%2C~22Rectangle12~22%2C12302%2C11081%2C14896%2C1376%2C%2C~22%23345678~22)",
+                                  "v": "0"
+                                }
+                              },
+                              {
+                                "n": "sheetsource",
+                                "cl": "StringAttribute",
+                                "o-vl": {
+                                  "v": "name",
+                                  "t": "s"
+                                }
+                              }
+                            ]
+                          },
+                          {
+                            "n": "textformat",
+                            "cl": "TextFormatAttributes",
+                            "pl": "tl:TextFormatAttributes.Template",
+                            "a-al": [
+                              {
+                                "n": "richtext",
+                                "o-vl": {
+                                  "v": "false",
+                                  "t": "b"
+                                }
+                              }
+                            ]
+                          }
+                        ]
+                      },
+                      "o-name": {
+                        "v": "Rectangle12",
+                        "t": "s"
+                      },
+                      "o-pin": {
+                        "o-p": {
+                          "o-x": {
+                            "v": "12302"
+                          },
+                          "o-y": {
+                            "v": "11081"
+                          }
+                        },
+                        "o-lp": {
+                          "o-x": {
+                            "f": "WIDTH%20*%200.5",
+                            "v": "7448"
+                          },
+                          "o-y": {
+                            "f": "HEIGHT%20*%200.5",
+                            "v": "688"
+                          }
+                        }
+                      },
+                      "o-size": {
+                        "o-w": {
+                          "v": "14896"
+                        },
+                        "o-h": {
+                          "v": "1376"
+                        }
+                      },
+                      "o-shape": {
+                        "type": "rectangle"
+                      },
+                      "type": "node"
+                    },
+                    {
+                      "id": "692699117567",
+                      "parentid": "1028",
+                      "o-al": {
+                        "n": "model.attributes",
+                        "cl": "JSG.AttributeList",
+                        "a-al": [
+                          {
+                            "n": "graphitem",
+                            "cl": "ItemAttributes",
+                            "a-al": [
+                              {
+                                "n": "sheetformula",
+                                "o-vl": {
+                                  "f": "DRAW.BEZIER(~22692699117567~22%2C%2C~22Bezier1~22%2C17647%2C13394%2C212%2C1164)",
+                                  "v": "0"
+                                }
+                              },
+                              {
+                                "n": "sheetsource",
+                                "cl": "StringAttribute",
+                                "o-vl": {
+                                  "v": "name",
+                                  "t": "s"
+                                }
+                              }
+                            ]
+                          }
+                        ]
+                      },
+                      "o-type": {
+                        "v": "roundRectCornerCutSame",
+                        "t": "s"
+                      },
+                      "o-name": {
+                        "v": "Bezier1",
+                        "t": "s"
+                      },
+                      "o-pin": {
+                        "o-p": {
+                          "o-x": {
+                            "v": "17647"
+                          },
+                          "o-y": {
+                            "v": "13394"
+                          }
+                        },
+                        "o-lp": {
+                          "o-x": {
+                            "f": "WIDTH%20*%200.5",
+                            "v": "106"
+                          },
+                          "o-y": {
+                            "f": "HEIGHT%20*%200.5",
+                            "v": "582"
+                          }
+                        }
+                      },
+                      "o-size": {
+                        "o-w": {
+                          "v": "212"
+                        },
+                        "o-h": {
+                          "v": "1164"
+                        }
+                      },
+                      "o-rscoordinates": {
+                        "a-c": [
+                          {
+                            "name": "ROUND",
+                            "xtype": "14",
+                            "ytype": "-1",
+                            "xMax": "0.5",
+                            "o-x": {
+                              "v": "0.10"
+                            },
+                            "o-y": {
+                              "v": "0.00"
+                            }
+                          },
+                          {
+                            "name": "ROUND2",
+                            "xtype": "13",
+                            "ytype": "-1",
+                            "xMax": "0.5",
+                            "yMin": "1",
+                            "yMax": "1",
+                            "o-x": {
+                              "v": "0.00"
+                            },
+                            "o-y": {
+                              "v": "1.00"
+                            }
+                          }
+                        ]
+                      },
+                      "o-shape": {
+                        "type": "bezier",
+                        "o-cs": {
+                          "a-c": [
+                            {
+                              "o-x": {
+                                "f": "MIN(WIDTH%2C%20HEIGHT)%20*%20ROUND",
+                                "v": "0"
+                              },
+                              "o-y": {
+                                "v": "0"
+                              }
+                            },
+                            {
+                              "o-x": {
+                                "f": "WIDTH%20-%20MIN(WIDTH%2C%20HEIGHT)%20*%20ROUND",
+                                "v": "0"
+                              },
+                              "o-y": {
+                                "v": "0"
+                              }
+                            },
+                            {
+                              "o-x": {
+                                "f": "WIDTH",
+                                "v": "212"
+                              },
+                              "o-y": {
+                                "f": "MIN(WIDTH%2C%20HEIGHT)%20*%20ROUND",
+                                "v": "0"
+                              }
+                            },
+                            {
+                              "o-x": {
+                                "f": "WIDTH",
+                                "v": "212"
+                              },
+                              "o-y": {
+                                "f": "HEIGHT%20-%20ROUND2%20*%20MIN(WIDTH%2C%20HEIGHT)",
+                                "v": "0"
+                              }
+                            },
+                            {
+                              "o-x": {
+                                "f": "WIDTH%20-%20MIN(WIDTH%2C%20HEIGHT)%20*%20ROUND2",
+                                "v": "0"
+                              },
+                              "o-y": {
+                                "f": "HEIGHT",
+                                "v": "1164"
+                              }
+                            },
+                            {
+                              "o-x": {
+                                "f": "MIN(WIDTH%2C%20HEIGHT)%20*%20ROUND2",
+                                "v": "0"
+                              },
+                              "o-y": {
+                                "f": "HEIGHT",
+                                "v": "1164"
+                              }
+                            },
+                            {
+                              "o-x": {
+                                "v": "0"
+                              },
+                              "o-y": {
+                                "f": "HEIGHT%20-%20MIN(WIDTH%2C%20HEIGHT)%20*%20ROUND2",
+                                "v": "0"
+                              }
+                            },
+                            {
+                              "o-x": {
+                                "v": "0"
+                              },
+                              "o-y": {
+                                "f": "MIN(WIDTH%2C%20HEIGHT)%20*%20ROUND",
+                                "v": "0"
+                              }
+                            }
+                          ]
+                        },
+                        "o-cpfrom": {
+                          "a-c": [
+                            {
+                              "o-x": {
+                                "f": "MIN(WIDTH%2C%20HEIGHT)%20*%20ROUND%20*%200.45",
+                                "v": "0"
+                              },
+                              "o-y": {
+                                "v": "0"
+                              }
+                            },
+                            {
+                              "o-x": {
+                                "f": "MIN(WIDTH%2C%20HEIGHT)%20*%200.6",
+                                "v": "0"
+                              },
+                              "o-y": {
+                                "v": "0"
+                              }
+                            },
+                            {
+                              "o-x": {
+                                "f": "WIDTH",
+                                "v": "212"
+                              },
+                              "o-y": {
+                                "f": "MIN(WIDTH%2C%20HEIGHT)%20*%20ROUND%20*%200.45",
+                                "v": "0"
+                              }
+                            },
+                            {
+                              "o-x": {
+                                "f": "WIDTH",
+                                "v": "212"
+                              },
+                              "o-y": {
+                                "f": "MIN(WIDTH%2C%20HEIGHT)%20*%200.6",
+                                "v": "0"
+                              }
+                            },
+                            {
+                              "o-x": {
+                                "f": "WIDTH%20-%20MIN(WIDTH%2C%20HEIGHT)%20*%20ROUND2%20*%200.45",
+                                "v": "0"
+                              },
+                              "o-y": {
+                                "f": "HEIGHT",
+                                "v": "1164"
+                              }
+                            },
+                            {
+                              "o-x": {
+                                "f": "MIN(WIDTH%2C%20HEIGHT)%20*%200.4",
+                                "v": "0"
+                              },
+                              "o-y": {
+                                "f": "HEIGHT",
+                                "v": "1164"
+                              }
+                            },
+                            {
+                              "o-x": {
+                                "v": "0"
+                              },
+                              "o-y": {
+                                "f": "HEIGHT%20-%20MIN(WIDTH%2C%20HEIGHT)%20*%20ROUND2%20*%200.45",
+                                "v": "0"
+                              }
+                            },
+                            {
+                              "o-x": {
+                                "v": "0"
+                              },
+                              "o-y": {
+                                "f": "MIN(WIDTH%2C%20HEIGHT)%20*%200.4",
+                                "v": "0"
+                              }
+                            }
+                          ]
+                        },
+                        "o-cpto": {
+                          "a-c": [
+                            {
+                              "o-x": {
+                                "f": "MIN(WIDTH%2C%20HEIGHT)%20*%200.4",
+                                "v": "0"
+                              },
+                              "o-y": {
+                                "v": "0"
+                              }
+                            },
+                            {
+                              "o-x": {
+                                "f": "WIDTH%20-%20MIN(WIDTH%2C%20HEIGHT)%20*%20ROUND%20*%200.45",
+                                "v": "0"
+                              },
+                              "o-y": {
+                                "v": "0"
+                              }
+                            },
+                            {
+                              "o-x": {
+                                "f": "WIDTH",
+                                "v": "212"
+                              },
+                              "o-y": {
+                                "f": "MIN(WIDTH%2C%20HEIGHT)%20*%200.4",
+                                "v": "0"
+                              }
+                            },
+                            {
+                              "o-x": {
+                                "f": "WIDTH",
+                                "v": "212"
+                              },
+                              "o-y": {
+                                "f": "HEIGHT%20-%20MIN(WIDTH%2C%20HEIGHT)%20*%20ROUND2%20*%200.45",
+                                "v": "0"
+                              }
+                            },
+                            {
+                              "o-x": {
+                                "f": "MIN(WIDTH%2C%20HEIGHT)%20*%200.6",
+                                "v": "0"
+                              },
+                              "o-y": {
+                                "f": "HEIGHT",
+                                "v": "1164"
+                              }
+                            },
+                            {
+                              "o-x": {
+                                "f": "MIN(WIDTH%2C%20HEIGHT)%20*%20ROUND2%20*%200.45",
+                                "v": "0"
+                              },
+                              "o-y": {
+                                "f": "HEIGHT",
+                                "v": "1164"
+                              }
+                            },
+                            {
+                              "o-x": {
+                                "v": "0"
+                              },
+                              "o-y": {
+                                "f": "MIN(WIDTH%2C%20HEIGHT)%20*%200.6",
+                                "v": "0"
+                              }
+                            },
+                            {
+                              "o-x": {
+                                "v": "0"
+                              },
+                              "o-y": {
+                                "f": "MIN(WIDTH%2C%20HEIGHT)%20*%20ROUND%20*%200.45",
+                                "v": "0"
+                              }
+                            }
+                          ],
+                          "pie": "false"
+                        }
+                      },
+                      "a-graphitem": [
+                        {
+                          "id": "426951475952",
+                          "parentid": "692699117567",
+                          "o-al": {
+                            "n": "model.attributes",
+                            "cl": "JSG.AttributeList",
+                            "a-al": [
+                              {
+                                "n": "format",
+                                "cl": "FormatAttributes",
+                                "a-al": [
+                                  {
+                                    "n": "fillcolor",
+                                    "o-vl": {
+                                      "v": "%23ff0000",
+                                      "t": "s"
+                                    }
+                                  }
+                                ]
+                              },
+                              {
+                                "n": "graphitem",
+                                "cl": "ItemAttributes",
+                                "a-al": [
+                                  {
+                                    "n": "sheetformula",
+                                    "o-vl": {
+                                      "f": "DRAW.ELLIPSE(~22426951475952~22%2C~22Bezier1~22%2C~22Ellipse1~22%2C106%2C1032%2C529%2C529%2C%2C~22%23ff0000~22)",
+                                      "v": "0"
+                                    }
+                                  },
+                                  {
+                                    "n": "sheetsource",
+                                    "cl": "StringAttribute",
+                                    "o-vl": {
+                                      "v": "name",
+                                      "t": "s"
+                                    }
+                                  }
+                                ]
+                              }
+                            ]
+                          },
+                          "o-name": {
+                            "v": "Ellipse1",
+                            "t": "s"
+                          },
+                          "o-pin": {
+                            "o-p": {
+                              "o-x": {
+                                "v": "106"
+                              },
+                              "o-y": {
+                                "v": "1032"
+                              }
+                            },
+                            "o-lp": {
+                              "o-x": {
+                                "f": "WIDTH%20*%200.5",
+                                "v": "265"
+                              },
+                              "o-y": {
+                                "f": "HEIGHT%20*%200.5",
+                                "v": "265"
+                              }
+                            }
+                          },
+                          "o-size": {
+                            "o-w": {
+                              "v": "529"
+                            },
+                            "o-h": {
+                              "v": "529"
+                            }
+                          },
+                          "o-shape": {
+                            "type": "ellipse",
+                            "o-cs": {
+                              "a-c": [
+                                {
+                                  "o-x": {
+                                    "f": "WIDTH%20*%200.5",
+                                    "v": "265"
+                                  },
+                                  "o-y": {
+                                    "v": "0"
+                                  }
+                                },
+                                {
+                                  "o-x": {
+                                    "f": "WIDTH",
+                                    "v": "529"
+                                  },
+                                  "o-y": {
+                                    "f": "HEIGHT%20*%200.5",
+                                    "v": "265"
+                                  }
+                                },
+                                {
+                                  "o-x": {
+                                    "f": "WIDTH%20*%200.5",
+                                    "v": "265"
+                                  },
+                                  "o-y": {
+                                    "f": "HEIGHT",
+                                    "v": "529"
+                                  }
+                                },
+                                {
+                                  "o-x": {
+                                    "v": "0"
+                                  },
+                                  "o-y": {
+                                    "f": "HEIGHT%20*%200.5",
+                                    "v": "265"
+                                  }
+                                }
+                              ]
+                            },
+                            "o-cpfrom": {
+                              "a-c": [
+                                {
+                                  "o-x": {
+                                    "f": "WIDTH%20*%200.225",
+                                    "v": "119"
+                                  },
+                                  "o-y": {
+                                    "v": "0"
+                                  }
+                                },
+                                {
+                                  "o-x": {
+                                    "f": "WIDTH",
+                                    "v": "529"
+                                  },
+                                  "o-y": {
+                                    "f": "HEIGHT%20*%200.225",
+                                    "v": "119"
+                                  }
+                                },
+                                {
+                                  "o-x": {
+                                    "f": "WIDTH%20*%200.775",
+                                    "v": "410"
+                                  },
+                                  "o-y": {
+                                    "f": "HEIGHT",
+                                    "v": "529"
+                                  }
+                                },
+                                {
+                                  "o-x": {
+                                    "v": "0"
+                                  },
+                                  "o-y": {
+                                    "f": "HEIGHT%20*%200.775",
+                                    "v": "410"
+                                  }
+                                }
+                              ]
+                            },
+                            "o-cpto": {
+                              "a-c": [
+                                {
+                                  "o-x": {
+                                    "f": "WIDTH%20*%200.775",
+                                    "v": "410"
+                                  },
+                                  "o-y": {
+                                    "v": "0"
+                                  }
+                                },
+                                {
+                                  "o-x": {
+                                    "f": "WIDTH",
+                                    "v": "529"
+                                  },
+                                  "o-y": {
+                                    "f": "HEIGHT%20*%200.775",
+                                    "v": "410"
+                                  }
+                                },
+                                {
+                                  "o-x": {
+                                    "f": "WIDTH%20*%200.225",
+                                    "v": "119"
+                                  },
+                                  "o-y": {
+                                    "f": "HEIGHT",
+                                    "v": "529"
+                                  }
+                                },
+                                {
+                                  "o-x": {
+                                    "v": "0"
+                                  },
+                                  "o-y": {
+                                    "f": "HEIGHT%20*%200.225",
+                                    "v": "119"
+                                  }
+                                }
+                              ],
+                              "pie": "false"
+                            }
+                          },
+                          "type": "node"
+                        }
+                      ],
+                      "type": "node"
+                    }
+                  ]
+                },
+                "o-defaultcell": {
+                  "o-cell": {
+                    "o-f": {
+                      "o-fillcolor": {
+                        "v": "%23ffffff",
+                        "t": "s"
+                      },
+                      "o-fillstyle": {
+                        "v": "1"
+                      }
+                    }
+                  }
+                },
+                "o-data": {
+                  "a-r": [
+                    {
+                      "n": "0",
+                      "a-c": [
+                        {
+                          "n": "6",
+                          "o-cell": {
+                            "o-t": {
+                              "o-numberformat": {
+                                "v": "h%3Amm%3Ass%20AM%2FPM",
+                                "t": "s"
+                              },
+                              "o-localculture": {
+                                "v": "time%3Ben",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "7",
+                          "o-cell": {
+                            "o-t": {
+                              "o-numberformat": {
+                                "v": "h%3Amm%3Ass",
+                                "t": "s"
+                              },
+                              "o-localculture": {
+                                "v": "time%3Ben",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        }
+                      ]
+                    },
+                    {
+                      "n": "1",
+                      "a-c": [
+                        {
+                          "n": "3",
+                          "o-cell": {
+                            "o-t": {
+                              "o-fontstyle": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "7",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "8",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "9",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "10",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "11",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "12",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "13",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "14",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        }
+                      ]
+                    },
+                    {
+                      "n": "2",
+                      "a-c": [
+                        {
+                          "n": "4",
+                          "o-cell": {
+                            "o-t": {
+                              "o-fontstyle": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "7",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            },
+                            "o-t": {
+                              "o-fontsize": {
+                                "v": "12"
+                              },
+                              "o-fontcolor": {
+                                "v": "%230f4db5",
+                                "t": "s"
+                              }
+                            },
+                            "o-a": {
+                              "o-leftbordercolor": {
+                                "v": "%230887fb",
+                                "t": "s"
+                              },
+                              "o-topbordercolor": {
+                                "v": "%230887fb",
+                                "t": "s"
+                              },
+                              "o-rightbordercolor": {
+                                "v": "%230887fb",
+                                "t": "s"
+                              },
+                              "o-bottombordercolor": {
+                                "v": "%230887fb",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "8",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            },
+                            "o-t": {
+                              "o-halign": {
+                                "v": "1"
+                              },
+                              "o-fontsize": {
+                                "v": "12"
+                              },
+                              "o-fontcolor": {
+                                "v": "%231758ab",
+                                "t": "s"
+                              }
+                            },
+                            "o-a": {
+                              "o-leftbordercolor": {
+                                "v": "%23f8e71c",
+                                "t": "s"
+                              },
+                              "o-topbordercolor": {
+                                "v": "%23f8e71c",
+                                "t": "s"
+                              },
+                              "o-rightbordercolor": {
+                                "v": "%23f8e71c",
+                                "t": "s"
+                              },
+                              "o-bottombordercolor": {
+                                "v": "%23f8e71c",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "9",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            },
+                            "o-t": {
+                              "o-halign": {
+                                "v": "1"
+                              },
+                              "o-fontsize": {
+                                "v": "12"
+                              },
+                              "o-fontcolor": {
+                                "v": "%231758ab",
+                                "t": "s"
+                              }
+                            },
+                            "o-a": {
+                              "o-leftbordercolor": {
+                                "v": "%23f8e71c",
+                                "t": "s"
+                              },
+                              "o-topbordercolor": {
+                                "v": "%23f8e71c",
+                                "t": "s"
+                              },
+                              "o-rightbordercolor": {
+                                "v": "%23f8e71c",
+                                "t": "s"
+                              },
+                              "o-bottombordercolor": {
+                                "v": "%23f8e71c",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "10",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "11",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "12",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "13",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "14",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        }
+                      ]
+                    },
+                    {
+                      "n": "3",
+                      "a-c": [
+                        {
+                          "n": "3",
+                          "o-cell": {
+                            "o-a": {
+                              "o-key": {
+                                "v": "true",
+                                "t": "b"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "5",
+                          "o-cell": {
+                            "o-t": {
+                              "o-numberformat": {
+                                "v": "0",
+                                "t": "s"
+                              },
+                              "o-localculture": {
+                                "v": "number%3B0%3Bfalse",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "6",
+                          "o-cell": {
+                            "o-t": {
+                              "o-numberformat": {
+                                "v": "h%3Amm%3Ass%20AM%2FPM",
+                                "t": "s"
+                              },
+                              "o-localculture": {
+                                "v": "time%3Ben",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "7",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            },
+                            "o-t": {
+                              "o-fontcolor": {
+                                "v": "%230f4db5",
+                                "t": "s"
+                              },
+                              "o-fontsize": {
+                                "v": "10"
+                              }
+                            },
+                            "o-a": {
+                              "o-key": {
+                                "v": "true",
+                                "t": "b"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "8",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            },
+                            "o-t": {
+                              "o-numberformat": {
+                                "v": "hh%3Amm%3Ass",
+                                "t": "s"
+                              },
+                              "o-localculture": {
+                                "v": "time%3Ben",
+                                "t": "s"
+                              },
+                              "o-halign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "9",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            },
+                            "o-t": {
+                              "o-halign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "10",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "11",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "12",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "13",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "14",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        }
+                      ]
+                    },
+                    {
+                      "n": "4",
+                      "a-c": [
+                        {
+                          "n": "3",
+                          "o-cell": {
+                            "o-a": {
+                              "o-key": {
+                                "v": "true",
+                                "t": "b"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "5",
+                          "o-cell": {
+                            "o-t": {
+                              "o-numberformat": {
+                                "v": "d~5C.m~5C.yyyy%20h%3Amm",
+                                "t": "s"
+                              },
+                              "o-localculture": {
+                                "v": "date%3Bde",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "6",
+                          "o-cell": {
+                            "o-t": {
+                              "o-numberformat": {
+                                "v": "h%3Amm%3Ass%20AM%2FPM",
+                                "t": "s"
+                              },
+                              "o-localculture": {
+                                "v": "time%3Ben",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "7",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            },
+                            "o-t": {
+                              "o-fontcolor": {
+                                "v": "%230f4db5",
+                                "t": "s"
+                              },
+                              "o-fontsize": {
+                                "v": "10"
+                              }
+                            },
+                            "o-a": {
+                              "o-key": {
+                                "v": "true",
+                                "t": "b"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "8",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            },
+                            "o-t": {
+                              "o-numberformat": {
+                                "v": "hh%3Amm%3Ass",
+                                "t": "s"
+                              },
+                              "o-localculture": {
+                                "v": "time%3Ben",
+                                "t": "s"
+                              },
+                              "o-halign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "9",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            },
+                            "o-t": {
+                              "o-halign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "10",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "11",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "12",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "13",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "14",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        }
+                      ]
+                    },
+                    {
+                      "n": "5",
+                      "a-c": [
+                        {
+                          "n": "3",
+                          "o-cell": {
+                            "o-a": {
+                              "o-key": {
+                                "v": "true",
+                                "t": "b"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "5",
+                          "o-cell": {
+                            "o-t": {
+                              "o-numberformat": {
+                                "v": "d~5C.m~5C.yyyy%20h%3Amm",
+                                "t": "s"
+                              },
+                              "o-localculture": {
+                                "v": "date%3Bde",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "6",
+                          "o-cell": {
+                            "o-t": {
+                              "o-numberformat": {
+                                "v": "h%3Amm%3Ass%20AM%2FPM",
+                                "t": "s"
+                              },
+                              "o-localculture": {
+                                "v": "time%3Ben",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "7",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            },
+                            "o-t": {
+                              "o-fontcolor": {
+                                "v": "%230f4db5",
+                                "t": "s"
+                              },
+                              "o-fontsize": {
+                                "v": "10"
+                              }
+                            },
+                            "o-a": {
+                              "o-key": {
+                                "v": "true",
+                                "t": "b"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "8",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            },
+                            "o-t": {
+                              "o-numberformat": {
+                                "v": "hh%3Amm%3Ass",
+                                "t": "s"
+                              },
+                              "o-localculture": {
+                                "v": "time%3Ben",
+                                "t": "s"
+                              },
+                              "o-halign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "9",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            },
+                            "o-t": {
+                              "o-halign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "10",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "11",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "12",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "13",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "14",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        }
+                      ]
+                    },
+                    {
+                      "n": "6",
+                      "a-c": [
+                        {
+                          "n": "3",
+                          "o-cell": {
+                            "o-a": {
+                              "o-key": {
+                                "v": "true",
+                                "t": "b"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "5",
+                          "o-cell": {
+                            "o-t": {
+                              "o-numberformat": {
+                                "v": "d~5C.m~5C.yyyy%20h%3Amm",
+                                "t": "s"
+                              },
+                              "o-localculture": {
+                                "v": "date%3Bde",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "6",
+                          "o-cell": {
+                            "o-t": {
+                              "o-numberformat": {
+                                "v": "h%3Amm%3Ass%20AM%2FPM",
+                                "t": "s"
+                              },
+                              "o-localculture": {
+                                "v": "time%3Ben",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "7",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            },
+                            "o-t": {
+                              "o-fontcolor": {
+                                "v": "%230f4db5",
+                                "t": "s"
+                              },
+                              "o-fontsize": {
+                                "v": "10"
+                              }
+                            },
+                            "o-a": {
+                              "o-key": {
+                                "v": "true",
+                                "t": "b"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "8",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            },
+                            "o-t": {
+                              "o-numberformat": {
+                                "v": "hh%3Amm%3Ass",
+                                "t": "s"
+                              },
+                              "o-localculture": {
+                                "v": "time%3Ben",
+                                "t": "s"
+                              },
+                              "o-halign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "9",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            },
+                            "o-t": {
+                              "o-halign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "10",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "11",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "12",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "13",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "14",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        }
+                      ]
+                    },
+                    {
+                      "n": "7",
+                      "a-c": [
+                        {
+                          "n": "3",
+                          "o-cell": {
+                            "o-a": {
+                              "o-key": {
+                                "v": "true",
+                                "t": "b"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "5",
+                          "o-cell": {
+                            "o-t": {
+                              "o-numberformat": {
+                                "v": "d~5C.m~5C.yyyy%20h%3Amm",
+                                "t": "s"
+                              },
+                              "o-localculture": {
+                                "v": "date%3Bde",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "6",
+                          "o-cell": {
+                            "o-t": {
+                              "o-numberformat": {
+                                "v": "h%3Amm%3Ass%20AM%2FPM",
+                                "t": "s"
+                              },
+                              "o-localculture": {
+                                "v": "time%3Ben",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "7",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            },
+                            "o-t": {
+                              "o-fontcolor": {
+                                "v": "%230f4db5",
+                                "t": "s"
+                              },
+                              "o-fontsize": {
+                                "v": "10"
+                              }
+                            },
+                            "o-a": {
+                              "o-key": {
+                                "v": "true",
+                                "t": "b"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "8",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            },
+                            "o-t": {
+                              "o-numberformat": {
+                                "v": "hh%3Amm%3Ass",
+                                "t": "s"
+                              },
+                              "o-localculture": {
+                                "v": "time%3Ben",
+                                "t": "s"
+                              },
+                              "o-halign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "9",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            },
+                            "o-t": {
+                              "o-halign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "10",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "11",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "12",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "13",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "14",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        }
+                      ]
+                    },
+                    {
+                      "n": "8",
+                      "a-c": [
+                        {
+                          "n": "3",
+                          "o-cell": {
+                            "o-a": {
+                              "o-key": {
+                                "v": "true",
+                                "t": "b"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "5",
+                          "o-cell": {
+                            "o-t": {
+                              "o-numberformat": {
+                                "v": "d~5C.m~5C.yyyy%20h%3Amm",
+                                "t": "s"
+                              },
+                              "o-localculture": {
+                                "v": "date%3Bde",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "6",
+                          "o-cell": {
+                            "o-t": {
+                              "o-numberformat": {
+                                "v": "h%3Amm%3Ass%20AM%2FPM",
+                                "t": "s"
+                              },
+                              "o-localculture": {
+                                "v": "time%3Ben",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "7",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            },
+                            "o-t": {
+                              "o-fontcolor": {
+                                "v": "%230f4db5",
+                                "t": "s"
+                              },
+                              "o-fontsize": {
+                                "v": "10"
+                              }
+                            },
+                            "o-a": {
+                              "o-key": {
+                                "v": "true",
+                                "t": "b"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "8",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            },
+                            "o-t": {
+                              "o-numberformat": {
+                                "v": "hh%3Amm%3Ass",
+                                "t": "s"
+                              },
+                              "o-localculture": {
+                                "v": "time%3Ben",
+                                "t": "s"
+                              },
+                              "o-halign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "9",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            },
+                            "o-t": {
+                              "o-halign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "10",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "11",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "12",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "13",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "14",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        }
+                      ]
+                    },
+                    {
+                      "n": "9",
+                      "a-c": [
+                        {
+                          "n": "3",
+                          "o-cell": {
+                            "o-a": {
+                              "o-key": {
+                                "v": "true",
+                                "t": "b"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "5",
+                          "o-cell": {
+                            "o-t": {
+                              "o-numberformat": {
+                                "v": "d~5C.m~5C.yyyy%20h%3Amm",
+                                "t": "s"
+                              },
+                              "o-localculture": {
+                                "v": "date%3Bde",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "6",
+                          "o-cell": {
+                            "o-t": {
+                              "o-numberformat": {
+                                "v": "h%3Amm%3Ass%20AM%2FPM",
+                                "t": "s"
+                              },
+                              "o-localculture": {
+                                "v": "time%3Ben",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "7",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            },
+                            "o-t": {
+                              "o-fontcolor": {
+                                "v": "%230f4db5",
+                                "t": "s"
+                              },
+                              "o-fontsize": {
+                                "v": "10"
+                              }
+                            },
+                            "o-a": {
+                              "o-key": {
+                                "v": "true",
+                                "t": "b"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "8",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            },
+                            "o-t": {
+                              "o-numberformat": {
+                                "v": "hh%3Amm%3Ass",
+                                "t": "s"
+                              },
+                              "o-localculture": {
+                                "v": "time%3Ben",
+                                "t": "s"
+                              },
+                              "o-halign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "9",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            },
+                            "o-t": {
+                              "o-halign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "10",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "11",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "12",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "13",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "14",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        }
+                      ]
+                    },
+                    {
+                      "n": "10",
+                      "a-c": [
+                        {
+                          "n": "3",
+                          "o-cell": {
+                            "o-a": {
+                              "o-key": {
+                                "v": "true",
+                                "t": "b"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "5",
+                          "o-cell": {
+                            "o-t": {
+                              "o-numberformat": {
+                                "v": "d~5C.m~5C.yyyy%20h%3Amm",
+                                "t": "s"
+                              },
+                              "o-localculture": {
+                                "v": "date%3Bde",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "6",
+                          "o-cell": {
+                            "o-t": {
+                              "o-numberformat": {
+                                "v": "h%3Amm%3Ass%20AM%2FPM",
+                                "t": "s"
+                              },
+                              "o-localculture": {
+                                "v": "time%3Ben",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "7",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            },
+                            "o-t": {
+                              "o-fontcolor": {
+                                "v": "%230f4db5",
+                                "t": "s"
+                              },
+                              "o-fontsize": {
+                                "v": "10"
+                              }
+                            },
+                            "o-a": {
+                              "o-key": {
+                                "v": "true",
+                                "t": "b"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "8",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            },
+                            "o-t": {
+                              "o-numberformat": {
+                                "v": "hh%3Amm%3Ass",
+                                "t": "s"
+                              },
+                              "o-localculture": {
+                                "v": "time%3Ben",
+                                "t": "s"
+                              },
+                              "o-halign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "9",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            },
+                            "o-t": {
+                              "o-halign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "10",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "11",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "12",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "13",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "14",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        }
+                      ]
+                    },
+                    {
+                      "n": "11",
+                      "a-c": [
+                        {
+                          "n": "3",
+                          "o-cell": {
+                            "o-a": {
+                              "o-key": {
+                                "v": "true",
+                                "t": "b"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "5",
+                          "o-cell": {
+                            "o-t": {
+                              "o-numberformat": {
+                                "v": "d~5C.m~5C.yyyy%20h%3Amm",
+                                "t": "s"
+                              },
+                              "o-localculture": {
+                                "v": "date%3Bde",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "6",
+                          "o-cell": {
+                            "o-t": {
+                              "o-numberformat": {
+                                "v": "h%3Amm%3Ass%20AM%2FPM",
+                                "t": "s"
+                              },
+                              "o-localculture": {
+                                "v": "time%3Ben",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "7",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            },
+                            "o-t": {
+                              "o-fontcolor": {
+                                "v": "%230f4db5",
+                                "t": "s"
+                              },
+                              "o-fontsize": {
+                                "v": "10"
+                              }
+                            },
+                            "o-a": {
+                              "o-key": {
+                                "v": "true",
+                                "t": "b"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "8",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            },
+                            "o-t": {
+                              "o-numberformat": {
+                                "v": "hh%3Amm%3Ass",
+                                "t": "s"
+                              },
+                              "o-localculture": {
+                                "v": "time%3Ben",
+                                "t": "s"
+                              },
+                              "o-halign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "9",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            },
+                            "o-t": {
+                              "o-halign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "10",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "11",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "12",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "13",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "14",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        }
+                      ]
+                    },
+                    {
+                      "n": "12",
+                      "a-c": [
+                        {
+                          "n": "3",
+                          "o-cell": {
+                            "o-a": {
+                              "o-key": {
+                                "v": "true",
+                                "t": "b"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "5",
+                          "o-cell": {
+                            "o-t": {
+                              "o-numberformat": {
+                                "v": "d~5C.m~5C.yyyy%20h%3Amm",
+                                "t": "s"
+                              },
+                              "o-localculture": {
+                                "v": "date%3Bde",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "6",
+                          "o-cell": {
+                            "o-t": {
+                              "o-numberformat": {
+                                "v": "h%3Amm%3Ass%20AM%2FPM",
+                                "t": "s"
+                              },
+                              "o-localculture": {
+                                "v": "time%3Ben",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "7",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            },
+                            "o-t": {
+                              "o-fontcolor": {
+                                "v": "%230f4db5",
+                                "t": "s"
+                              },
+                              "o-fontsize": {
+                                "v": "10"
+                              }
+                            },
+                            "o-a": {
+                              "o-key": {
+                                "v": "true",
+                                "t": "b"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "8",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            },
+                            "o-t": {
+                              "o-numberformat": {
+                                "v": "hh%3Amm%3Ass",
+                                "t": "s"
+                              },
+                              "o-localculture": {
+                                "v": "time%3Ben",
+                                "t": "s"
+                              },
+                              "o-halign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "9",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            },
+                            "o-t": {
+                              "o-halign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "10",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "11",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "12",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "13",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "14",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        }
+                      ]
+                    },
+                    {
+                      "n": "13",
+                      "a-c": [
+                        {
+                          "n": "7",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            },
+                            "o-t": {
+                              "o-numberformat": {
+                                "v": "0.00",
+                                "t": "s"
+                              },
+                              "o-localculture": {
+                                "v": "number%3B2%3Bfalse",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "8",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "9",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "10",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "11",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "12",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "13",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "14",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5fef3",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        }
+                      ]
+                    },
+                    {
+                      "n": "15",
+                      "a-c": [
+                        {
+                          "n": "1",
+                          "o-cell": {
+                            "o-t": {
+                              "o-valign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "2",
+                          "o-cell": {
+                            "o-t": {
+                              "o-fontstyle": {
+                                "v": "1"
+                              },
+                              "o-valign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "7",
+                          "o-cell": {
+                            "o-t": {
+                              "o-valign": {
+                                "v": "1"
+                              },
+                              "o-fontstyle": {
+                                "v": "1"
+                              },
+                              "o-numberformat": {
+                                "v": "0.00",
+                                "t": "s"
+                              },
+                              "o-localculture": {
+                                "v": "number%3B2%3Bfalse",
+                                "t": "s"
+                              }
+                            }
+                          }
+                        }
+                      ]
+                    },
+                    {
+                      "n": "16",
+                      "a-c": [
+                        {
+                          "n": "1",
+                          "o-cell": {
+                            "o-t": {
+                              "o-valign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "2",
+                          "o-cell": {
+                            "o-t": {
+                              "o-fontstyle": {
+                                "v": "1"
+                              },
+                              "o-valign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "7",
+                          "o-cell": {
+                            "o-t": {
+                              "o-valign": {
+                                "v": "1"
+                              }
+                            },
+                            "o-a": {
+                              "o-key": {
+                                "v": "true",
+                                "t": "b"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "8",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5b5b5",
+                                "t": "s"
+                              }
+                            },
+                            "o-t": {
+                              "o-valign": {
+                                "v": "1"
+                              },
+                              "o-fontstyle": {
+                                "v": "1"
+                              },
+                              "o-fontcolor": {
+                                "v": "%234a90e2",
+                                "t": "s"
+                              }
+                            },
+                            "o-a": {
+                              "o-key": {
+                                "v": "true",
+                                "t": "b"
+                              },
+                              "o-leftborderwidth": {
+                                "v": "8"
+                              },
+                              "o-topborderwidth": {
+                                "v": "8"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "9",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5b5b5",
+                                "t": "s"
+                              }
+                            },
+                            "o-a": {
+                              "o-leftborderwidth": {
+                                "v": "8"
+                              },
+                              "o-topborderwidth": {
+                                "v": "8"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "10",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5b5b5",
+                                "t": "s"
+                              }
+                            },
+                            "o-a": {
+                              "o-leftborderwidth": {
+                                "v": "8"
+                              },
+                              "o-topborderwidth": {
+                                "v": "8"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "11",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5b5b5",
+                                "t": "s"
+                              }
+                            },
+                            "o-a": {
+                              "o-leftborderwidth": {
+                                "v": "8"
+                              },
+                              "o-topborderwidth": {
+                                "v": "8"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "12",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5b5b5",
+                                "t": "s"
+                              }
+                            },
+                            "o-a": {
+                              "o-leftborderwidth": {
+                                "v": "8"
+                              },
+                              "o-topborderwidth": {
+                                "v": "8"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "13",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5b5b5",
+                                "t": "s"
+                              }
+                            },
+                            "o-a": {
+                              "o-leftborderwidth": {
+                                "v": "8"
+                              },
+                              "o-topborderwidth": {
+                                "v": "8"
+                              }
+                            }
+                          }
+                        }
+                      ]
+                    },
+                    {
+                      "n": "17",
+                      "a-c": [
+                        {
+                          "n": "1",
+                          "o-cell": {
+                            "o-t": {
+                              "o-valign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "2",
+                          "o-cell": {
+                            "o-t": {
+                              "o-valign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "6",
+                          "o-cell": {
+                            "o-t": {
+                              "o-valign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "7",
+                          "o-cell": {
+                            "o-t": {
+                              "o-valign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "8",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5b5b5",
+                                "t": "s"
+                              }
+                            },
+                            "o-t": {
+                              "o-valign": {
+                                "v": "1"
+                              }
+                            },
+                            "o-a": {
+                              "o-leftborderwidth": {
+                                "v": "8"
+                              },
+                              "o-topborderwidth": {
+                                "v": "8"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "9",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5b5b5",
+                                "t": "s"
+                              }
+                            },
+                            "o-t": {
+                              "o-valign": {
+                                "v": "1"
+                              },
+                              "o-fontsize": {
+                                "v": "24"
+                              }
+                            },
+                            "o-a": {
+                              "o-leftborderwidth": {
+                                "v": "8"
+                              },
+                              "o-topborderwidth": {
+                                "v": "8"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "10",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5b5b5",
+                                "t": "s"
+                              }
+                            },
+                            "o-t": {
+                              "o-valign": {
+                                "v": "1"
+                              }
+                            },
+                            "o-a": {
+                              "o-leftborderwidth": {
+                                "v": "8"
+                              },
+                              "o-topborderwidth": {
+                                "v": "8"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "11",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5b5b5",
+                                "t": "s"
+                              }
+                            },
+                            "o-a": {
+                              "o-leftborderwidth": {
+                                "v": "8"
+                              },
+                              "o-topborderwidth": {
+                                "v": "8"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "12",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5b5b5",
+                                "t": "s"
+                              }
+                            },
+                            "o-a": {
+                              "o-leftborderwidth": {
+                                "v": "8"
+                              },
+                              "o-topborderwidth": {
+                                "v": "8"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "13",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5b5b5",
+                                "t": "s"
+                              }
+                            },
+                            "o-a": {
+                              "o-leftborderwidth": {
+                                "v": "8"
+                              },
+                              "o-topborderwidth": {
+                                "v": "8"
+                              }
+                            }
+                          }
+                        }
+                      ]
+                    },
+                    {
+                      "n": "18",
+                      "a-c": [
+                        {
+                          "n": "2",
+                          "o-cell": {
+                            "o-t": {
+                              "o-fontstyle": {
+                                "v": "1"
+                              },
+                              "o-valign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "7",
+                          "o-cell": {
+                            "o-t": {
+                              "o-valign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "8",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5b5b5",
+                                "t": "s"
+                              }
+                            },
+                            "o-a": {
+                              "o-leftborderwidth": {
+                                "v": "8"
+                              },
+                              "o-topborderwidth": {
+                                "v": "8"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "9",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5b5b5",
+                                "t": "s"
+                              }
+                            },
+                            "o-a": {
+                              "o-leftborderwidth": {
+                                "v": "8"
+                              },
+                              "o-topborderwidth": {
+                                "v": "8"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "10",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5b5b5",
+                                "t": "s"
+                              }
+                            },
+                            "o-t": {
+                              "o-valign": {
+                                "v": "1"
+                              }
+                            },
+                            "o-a": {
+                              "o-leftborderwidth": {
+                                "v": "8"
+                              },
+                              "o-topborderwidth": {
+                                "v": "8"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "11",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5b5b5",
+                                "t": "s"
+                              }
+                            },
+                            "o-a": {
+                              "o-leftborderwidth": {
+                                "v": "8"
+                              },
+                              "o-topborderwidth": {
+                                "v": "8"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "12",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5b5b5",
+                                "t": "s"
+                              }
+                            },
+                            "o-a": {
+                              "o-leftborderwidth": {
+                                "v": "8"
+                              },
+                              "o-topborderwidth": {
+                                "v": "8"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "13",
+                          "o-cell": {
+                            "o-f": {
+                              "o-fillcolor": {
+                                "v": "%23b5b5b5",
+                                "t": "s"
+                              }
+                            },
+                            "o-a": {
+                              "o-leftborderwidth": {
+                                "v": "8"
+                              },
+                              "o-topborderwidth": {
+                                "v": "8"
+                              }
+                            }
+                          }
+                        }
+                      ]
+                    },
+                    {
+                      "n": "19",
+                      "a-c": [
+                        {
+                          "n": "1",
+                          "o-cell": {
+                            "o-t": {
+                              "o-valign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "2",
+                          "o-cell": {
+                            "o-t": {
+                              "o-fontstyle": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "10",
+                          "o-cell": {
+                            "o-t": {
+                              "o-valign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        }
+                      ]
+                    },
+                    {
+                      "n": "20",
+                      "a-c": [
+                        {
+                          "n": "1",
+                          "o-cell": {
+                            "o-t": {
+                              "o-valign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "2",
+                          "o-cell": {
+                            "o-t": {
+                              "o-fontstyle": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "10",
+                          "o-cell": {
+                            "o-t": {
+                              "o-valign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        }
+                      ]
+                    },
+                    {
+                      "n": "21",
+                      "a-c": [
+                        {
+                          "n": "1",
+                          "o-cell": {
+                            "o-t": {
+                              "o-valign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "2",
+                          "o-cell": {
+                            "o-t": {
+                              "o-fontstyle": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "10",
+                          "o-cell": {
+                            "o-t": {
+                              "o-valign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        }
+                      ]
+                    },
+                    {
+                      "n": "22",
+                      "a-c": [
+                        {
+                          "n": "1",
+                          "o-cell": {
+                            "o-t": {
+                              "o-valign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "2",
+                          "o-cell": {
+                            "o-t": {
+                              "o-valign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "3",
+                          "o-cell": {
+                            "o-t": {
+                              "o-valign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "4",
+                          "o-cell": {
+                            "o-t": {
+                              "o-valign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "5",
+                          "o-cell": {
+                            "o-t": {
+                              "o-valign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "6",
+                          "o-cell": {
+                            "o-t": {
+                              "o-valign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "7",
+                          "o-cell": {
+                            "o-t": {
+                              "o-valign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        }
+                      ]
+                    },
+                    {
+                      "n": "23",
+                      "a-c": [
+                        {
+                          "n": "1",
+                          "o-cell": {
+                            "o-t": {
+                              "o-valign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "2",
+                          "o-cell": {
+                            "o-t": {
+                              "o-valign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "3",
+                          "o-cell": {
+                            "o-t": {
+                              "o-valign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "4",
+                          "o-cell": {
+                            "o-t": {
+                              "o-valign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "5",
+                          "o-cell": {
+                            "o-t": {
+                              "o-valign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "6",
+                          "o-cell": {
+                            "o-t": {
+                              "o-valign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "7",
+                          "o-cell": {
+                            "o-t": {
+                              "o-valign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        }
+                      ]
+                    },
+                    {
+                      "n": "24",
+                      "a-c": [
+                        {
+                          "n": "1",
+                          "o-cell": {
+                            "o-t": {
+                              "o-valign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "2",
+                          "o-cell": {
+                            "o-t": {
+                              "o-valign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "3",
+                          "o-cell": {
+                            "o-t": {
+                              "o-valign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "4",
+                          "o-cell": {
+                            "o-t": {
+                              "o-valign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "5",
+                          "o-cell": {
+                            "o-t": {
+                              "o-valign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "6",
+                          "o-cell": {
+                            "o-t": {
+                              "o-valign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "7",
+                          "o-cell": {
+                            "o-t": {
+                              "o-valign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        }
+                      ]
+                    },
+                    {
+                      "n": "25",
+                      "a-c": [
+                        {
+                          "n": "1",
+                          "o-cell": {
+                            "o-t": {
+                              "o-valign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "2",
+                          "o-cell": {
+                            "o-t": {
+                              "o-valign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "3",
+                          "o-cell": {
+                            "o-t": {
+                              "o-valign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "4",
+                          "o-cell": {
+                            "o-t": {
+                              "o-valign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "5",
+                          "o-cell": {
+                            "o-t": {
+                              "o-valign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "6",
+                          "o-cell": {
+                            "o-t": {
+                              "o-valign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "7",
+                          "o-cell": {
+                            "o-t": {
+                              "o-valign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        }
+                      ]
+                    },
+                    {
+                      "n": "26",
+                      "a-c": [
+                        {
+                          "n": "1",
+                          "o-cell": {
+                            "o-t": {
+                              "o-valign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "2",
+                          "o-cell": {
+                            "o-t": {
+                              "o-valign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "3",
+                          "o-cell": {
+                            "o-t": {
+                              "o-valign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "4",
+                          "o-cell": {
+                            "o-t": {
+                              "o-valign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "5",
+                          "o-cell": {
+                            "o-t": {
+                              "o-valign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "6",
+                          "o-cell": {
+                            "o-t": {
+                              "o-valign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "7",
+                          "o-cell": {
+                            "o-t": {
+                              "o-valign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        }
+                      ]
+                    },
+                    {
+                      "n": "27",
+                      "a-c": [
+                        {
+                          "n": "1",
+                          "o-cell": {
+                            "o-t": {
+                              "o-valign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "2",
+                          "o-cell": {
+                            "o-t": {
+                              "o-valign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "3",
+                          "o-cell": {
+                            "o-t": {
+                              "o-valign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "4",
+                          "o-cell": {
+                            "o-t": {
+                              "o-valign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "5",
+                          "o-cell": {
+                            "o-t": {
+                              "o-valign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "6",
+                          "o-cell": {
+                            "o-t": {
+                              "o-valign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        },
+                        {
+                          "n": "7",
+                          "o-cell": {
+                            "o-t": {
+                              "o-valign": {
+                                "v": "1"
+                              }
+                            }
+                          }
+                        }
+                      ]
+                    }
+                  ]
+                }
+              }
+            }
+          ],
+          "o-images": {}
+        },
+        "machineId": "S1-EB3RpyP"
+      }
+    }
+  ],
+  "streams": [
+    {
+      "id": "HJZR0U1xSI",
+      "name": "AASRESTTestProducer",
+      "owner": null,
+      "disabled": false,
+      "className": "ProducerConfiguration",
+      "lastModified": "2020-09-09T12:55:45.437Z",
+      "lastAccessed": "2020-03-06T15:05:58.112Z",
+      "connector": {
+        "_id": "S1lML8ygr8",
+        "id": "S1lML8ygr8",
+        "className": "ConnectorConfiguration",
+        "owner": null,
+        "disabled": false,
+        "lastModified": "2020-09-09T12:34:12.984Z",
+        "lastAccessed": "2020-03-06T15:03:38.128Z",
+        "isRef": true
+      },
+      "samplePayloads": null,
+      "mimeType": "auto"
+    },
+    {
+      "id": "S1lML8ygr8",
+      "name": "AASRESTTestProvider",
+      "owner": null,
+      "disabled": false,
+      "className": "ConnectorConfiguration",
+      "lastModified": "2020-09-09T12:55:45.436Z",
+      "lastAccessed": "2020-03-06T15:03:38.128Z",
+      "provider": {
+        "_id": "@cedalo/stream-rest-client",
+        "id": "@cedalo/stream-rest-client",
+        "className": "ProviderConfiguration",
+        "owner": null,
+        "disabled": null,
+        "lastModified": null,
+        "lastAccessed": null,
+        "isRef": true
+      },
+      "baseUrl": "",
+      "userName": "",
+      "password": ""
+    }
+  ]
+}
\ No newline at end of file
diff --git a/examples/basyx.streamsheets/docker-compose.yml b/examples/basyx.streamsheets/docker-compose.yml
new file mode 100644
index 0000000..c4903f4
--- /dev/null
+++ b/examples/basyx.streamsheets/docker-compose.yml
@@ -0,0 +1,34 @@
+version: '3'
+services:
+
+  registry:
+    image: eclipsebasyx/aas-registry:1.0.1
+    container_name: dashboard-registry
+    ports:
+      - 4000:4000
+
+  dashboard-aas:
+    image: eclipsebasyx/dashboard-aas:0.1.0-SNAPSHOT
+    container_name: dashboard-aas
+    environment:
+      - BaSyxDashboardSubmodel_Min=15
+#      - BaSyxDashboardSubmodel_Max=30
+    ports:
+      - 6400:6400
+
+  aas-wrapper:
+    image: eclipsebasyx/aas-wrapper:0.1.0-SNAPSHOT
+    container_name: aas-wrapper
+    ports:
+      - 6500:6500
+
+  streamsheets:
+    image: cedalo/streamsheets:1.5
+    container_name: streamsheets
+    ports:
+      - 8081:8081
+      - 8083:8083
+      - 1883:1883
+    volumes:
+      - ./mosquitto:/etc/mosquitto-default-credentials
+      - ./streamsheets:/var/lib/mongodb
\ No newline at end of file
diff --git a/examples/basyx.streamsheets/readme.txt b/examples/basyx.streamsheets/readme.txt
new file mode 100644
index 0000000..5023bde
--- /dev/null
+++ b/examples/basyx.streamsheets/readme.txt
@@ -0,0 +1,12 @@
+HowTo: First Setup
+------------------
+
+1. Start docker-compose
+- Run "docker-compose up" in the /streamsheets/ folder
+
+2. Open in Browser (admin/admin)
+- http://localhost:8081/
+
+3. Import dashboard from JSON (drag & drop possible)
+
+4. Run Streamsheet
diff --git a/examples/basyx.streamsheets/start.bat b/examples/basyx.streamsheets/start.bat
new file mode 100644
index 0000000..83ed0d0
--- /dev/null
+++ b/examples/basyx.streamsheets/start.bat
@@ -0,0 +1 @@
+docker-compose up
diff --git a/examples/basyx.streamsheets/start.sh b/examples/basyx.streamsheets/start.sh
new file mode 100644
index 0000000..d935e43
--- /dev/null
+++ b/examples/basyx.streamsheets/start.sh
@@ -0,0 +1,2 @@
+#!/usr/bin/env sh
+docker-compose up
\ No newline at end of file
diff --git a/examples/basyx.streamsheets/stop.bat b/examples/basyx.streamsheets/stop.bat
new file mode 100644
index 0000000..58694d0
--- /dev/null
+++ b/examples/basyx.streamsheets/stop.bat
@@ -0,0 +1 @@
+docker-compose down
\ No newline at end of file
diff --git a/examples/basyx.streamsheets/stop.sh b/examples/basyx.streamsheets/stop.sh
new file mode 100644
index 0000000..f5139e2
--- /dev/null
+++ b/examples/basyx.streamsheets/stop.sh
@@ -0,0 +1,2 @@
+#!/usr/bin/env sh
+docker-compose down
\ No newline at end of file
diff --git a/examples/mvnw b/examples/mvnw
new file mode 100644
index 0000000..a16b543
--- /dev/null
+++ b/examples/mvnw
@@ -0,0 +1,310 @@
+#!/bin/sh
+# ----------------------------------------------------------------------------
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#    https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+# ----------------------------------------------------------------------------
+
+# ----------------------------------------------------------------------------
+# Maven Start Up Batch script
+#
+# Required ENV vars:
+# ------------------
+#   JAVA_HOME - location of a JDK home dir
+#
+# Optional ENV vars
+# -----------------
+#   M2_HOME - location of maven2's installed home dir
+#   MAVEN_OPTS - parameters passed to the Java VM when running Maven
+#     e.g. to debug Maven itself, use
+#       set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
+#   MAVEN_SKIP_RC - flag to disable loading of mavenrc files
+# ----------------------------------------------------------------------------
+
+if [ -z "$MAVEN_SKIP_RC" ] ; then
+
+  if [ -f /etc/mavenrc ] ; then
+    . /etc/mavenrc
+  fi
+
+  if [ -f "$HOME/.mavenrc" ] ; then
+    . "$HOME/.mavenrc"
+  fi
+
+fi
+
+# OS specific support.  $var _must_ be set to either true or false.
+cygwin=false;
+darwin=false;
+mingw=false
+case "`uname`" in
+  CYGWIN*) cygwin=true ;;
+  MINGW*) mingw=true;;
+  Darwin*) darwin=true
+    # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
+    # See https://developer.apple.com/library/mac/qa/qa1170/_index.html
+    if [ -z "$JAVA_HOME" ]; then
+      if [ -x "/usr/libexec/java_home" ]; then
+        export JAVA_HOME="`/usr/libexec/java_home`"
+      else
+        export JAVA_HOME="/Library/Java/Home"
+      fi
+    fi
+    ;;
+esac
+
+if [ -z "$JAVA_HOME" ] ; then
+  if [ -r /etc/gentoo-release ] ; then
+    JAVA_HOME=`java-config --jre-home`
+  fi
+fi
+
+if [ -z "$M2_HOME" ] ; then
+  ## resolve links - $0 may be a link to maven's home
+  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
+
+  saveddir=`pwd`
+
+  M2_HOME=`dirname "$PRG"`/..
+
+  # make it fully qualified
+  M2_HOME=`cd "$M2_HOME" && pwd`
+
+  cd "$saveddir"
+  # echo Using m2 at $M2_HOME
+fi
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched
+if $cygwin ; then
+  [ -n "$M2_HOME" ] &&
+    M2_HOME=`cygpath --unix "$M2_HOME"`
+  [ -n "$JAVA_HOME" ] &&
+    JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+  [ -n "$CLASSPATH" ] &&
+    CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
+fi
+
+# For Mingw, ensure paths are in UNIX format before anything is touched
+if $mingw ; then
+  [ -n "$M2_HOME" ] &&
+    M2_HOME="`(cd "$M2_HOME"; pwd)`"
+  [ -n "$JAVA_HOME" ] &&
+    JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
+fi
+
+if [ -z "$JAVA_HOME" ]; then
+  javaExecutable="`which javac`"
+  if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
+    # readlink(1) is not available as standard on Solaris 10.
+    readLink=`which readlink`
+    if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
+      if $darwin ; then
+        javaHome="`dirname \"$javaExecutable\"`"
+        javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
+      else
+        javaExecutable="`readlink -f \"$javaExecutable\"`"
+      fi
+      javaHome="`dirname \"$javaExecutable\"`"
+      javaHome=`expr "$javaHome" : '\(.*\)/bin'`
+      JAVA_HOME="$javaHome"
+      export JAVA_HOME
+    fi
+  fi
+fi
+
+if [ -z "$JAVACMD" ] ; then
+  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
+  else
+    JAVACMD="`which java`"
+  fi
+fi
+
+if [ ! -x "$JAVACMD" ] ; then
+  echo "Error: JAVA_HOME is not defined correctly." >&2
+  echo "  We cannot execute $JAVACMD" >&2
+  exit 1
+fi
+
+if [ -z "$JAVA_HOME" ] ; then
+  echo "Warning: JAVA_HOME environment variable is not set."
+fi
+
+CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
+
+# traverses directory structure from process work directory to filesystem root
+# first directory with .mvn subdirectory is considered project base directory
+find_maven_basedir() {
+
+  if [ -z "$1" ]
+  then
+    echo "Path not specified to find_maven_basedir"
+    return 1
+  fi
+
+  basedir="$1"
+  wdir="$1"
+  while [ "$wdir" != '/' ] ; do
+    if [ -d "$wdir"/.mvn ] ; then
+      basedir=$wdir
+      break
+    fi
+    # workaround for JBEAP-8937 (on Solaris 10/Sparc)
+    if [ -d "${wdir}" ]; then
+      wdir=`cd "$wdir/.."; pwd`
+    fi
+    # end of workaround
+  done
+  echo "${basedir}"
+}
+
+# concatenates all lines of a file
+concat_lines() {
+  if [ -f "$1" ]; then
+    echo "$(tr -s '\n' ' ' < "$1")"
+  fi
+}
+
+BASE_DIR=`find_maven_basedir "$(pwd)"`
+if [ -z "$BASE_DIR" ]; then
+  exit 1;
+fi
+
+##########################################################################################
+# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
+# This allows using the maven wrapper in projects that prohibit checking in binary data.
+##########################################################################################
+if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
+    if [ "$MVNW_VERBOSE" = true ]; then
+      echo "Found .mvn/wrapper/maven-wrapper.jar"
+    fi
+else
+    if [ "$MVNW_VERBOSE" = true ]; then
+      echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
+    fi
+    if [ -n "$MVNW_REPOURL" ]; then
+      jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
+    else
+      jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
+    fi
+    while IFS="=" read key value; do
+      case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
+      esac
+    done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
+    if [ "$MVNW_VERBOSE" = true ]; then
+      echo "Downloading from: $jarUrl"
+    fi
+    wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
+    if $cygwin; then
+      wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"`
+    fi
+
+    if command -v wget > /dev/null; then
+        if [ "$MVNW_VERBOSE" = true ]; then
+          echo "Found wget ... using wget"
+        fi
+        if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
+            wget "$jarUrl" -O "$wrapperJarPath"
+        else
+            wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath"
+        fi
+    elif command -v curl > /dev/null; then
+        if [ "$MVNW_VERBOSE" = true ]; then
+          echo "Found curl ... using curl"
+        fi
+        if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
+            curl -o "$wrapperJarPath" "$jarUrl" -f
+        else
+            curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f
+        fi
+
+    else
+        if [ "$MVNW_VERBOSE" = true ]; then
+          echo "Falling back to using Java to download"
+        fi
+        javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
+        # For Cygwin, switch paths to Windows format before running javac
+        if $cygwin; then
+          javaClass=`cygpath --path --windows "$javaClass"`
+        fi
+        if [ -e "$javaClass" ]; then
+            if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
+                if [ "$MVNW_VERBOSE" = true ]; then
+                  echo " - Compiling MavenWrapperDownloader.java ..."
+                fi
+                # Compiling the Java class
+                ("$JAVA_HOME/bin/javac" "$javaClass")
+            fi
+            if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
+                # Running the downloader
+                if [ "$MVNW_VERBOSE" = true ]; then
+                  echo " - Running MavenWrapperDownloader.java ..."
+                fi
+                ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
+            fi
+        fi
+    fi
+fi
+##########################################################################################
+# End of extension
+##########################################################################################
+
+export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
+if [ "$MVNW_VERBOSE" = true ]; then
+  echo $MAVEN_PROJECTBASEDIR
+fi
+MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin; then
+  [ -n "$M2_HOME" ] &&
+    M2_HOME=`cygpath --path --windows "$M2_HOME"`
+  [ -n "$JAVA_HOME" ] &&
+    JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
+  [ -n "$CLASSPATH" ] &&
+    CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
+  [ -n "$MAVEN_PROJECTBASEDIR" ] &&
+    MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
+fi
+
+# Provide a "standardized" way to retrieve the CLI args that will
+# work with both Windows and non-Windows executions.
+MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
+export MAVEN_CMD_LINE_ARGS
+
+WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
+
+exec "$JAVACMD" \
+  $MAVEN_OPTS \
+  -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
+  "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
+  ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
diff --git a/examples/mvnw.cmd b/examples/mvnw.cmd
new file mode 100644
index 0000000..c8d4337
--- /dev/null
+++ b/examples/mvnw.cmd
@@ -0,0 +1,182 @@
+@REM ----------------------------------------------------------------------------
+@REM Licensed to the Apache Software Foundation (ASF) under one
+@REM or more contributor license agreements.  See the NOTICE file
+@REM distributed with this work for additional information
+@REM regarding copyright ownership.  The ASF licenses this file
+@REM to you under the Apache License, Version 2.0 (the
+@REM "License"); you may not use this file except in compliance
+@REM with the License.  You may obtain a copy of the License at
+@REM
+@REM    https://www.apache.org/licenses/LICENSE-2.0
+@REM
+@REM Unless required by applicable law or agreed to in writing,
+@REM software distributed under the License is distributed on an
+@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+@REM KIND, either express or implied.  See the License for the
+@REM specific language governing permissions and limitations
+@REM under the License.
+@REM ----------------------------------------------------------------------------
+
+@REM ----------------------------------------------------------------------------
+@REM Maven Start Up Batch script
+@REM
+@REM Required ENV vars:
+@REM JAVA_HOME - location of a JDK home dir
+@REM
+@REM Optional ENV vars
+@REM M2_HOME - location of maven2's installed home dir
+@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
+@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
+@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
+@REM     e.g. to debug Maven itself, use
+@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
+@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
+@REM ----------------------------------------------------------------------------
+
+@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
+@echo off
+@REM set title of command window
+title %0
+@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
+@if "%MAVEN_BATCH_ECHO%" == "on"  echo %MAVEN_BATCH_ECHO%
+
+@REM set %HOME% to equivalent of $HOME
+if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
+
+@REM Execute a user defined script before this one
+if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
+@REM check for pre script, once with legacy .bat ending and once with .cmd ending
+if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
+if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
+:skipRcPre
+
+@setlocal
+
+set ERROR_CODE=0
+
+@REM To isolate internal variables from possible post scripts, we use another setlocal
+@setlocal
+
+@REM ==== START VALIDATION ====
+if not "%JAVA_HOME%" == "" goto OkJHome
+
+echo.
+echo Error: JAVA_HOME not found in your environment. >&2
+echo Please set the JAVA_HOME variable in your environment to match the >&2
+echo location of your Java installation. >&2
+echo.
+goto error
+
+:OkJHome
+if exist "%JAVA_HOME%\bin\java.exe" goto init
+
+echo.
+echo Error: JAVA_HOME is set to an invalid directory. >&2
+echo JAVA_HOME = "%JAVA_HOME%" >&2
+echo Please set the JAVA_HOME variable in your environment to match the >&2
+echo location of your Java installation. >&2
+echo.
+goto error
+
+@REM ==== END VALIDATION ====
+
+:init
+
+@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
+@REM Fallback to current working directory if not found.
+
+set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
+IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
+
+set EXEC_DIR=%CD%
+set WDIR=%EXEC_DIR%
+:findBaseDir
+IF EXIST "%WDIR%"\.mvn goto baseDirFound
+cd ..
+IF "%WDIR%"=="%CD%" goto baseDirNotFound
+set WDIR=%CD%
+goto findBaseDir
+
+:baseDirFound
+set MAVEN_PROJECTBASEDIR=%WDIR%
+cd "%EXEC_DIR%"
+goto endDetectBaseDir
+
+:baseDirNotFound
+set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
+cd "%EXEC_DIR%"
+
+:endDetectBaseDir
+
+IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
+
+@setlocal EnableExtensions EnableDelayedExpansion
+for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
+@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
+
+:endReadAdditionalConfig
+
+SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
+set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
+set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
+
+set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
+
+FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
+    IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
+)
+
+@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
+@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
+if exist %WRAPPER_JAR% (
+    if "%MVNW_VERBOSE%" == "true" (
+        echo Found %WRAPPER_JAR%
+    )
+) else (
+    if not "%MVNW_REPOURL%" == "" (
+        SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
+    )
+    if "%MVNW_VERBOSE%" == "true" (
+        echo Couldn't find %WRAPPER_JAR%, downloading it ...
+        echo Downloading from: %DOWNLOAD_URL%
+    )
+
+    powershell -Command "&{"^
+		"$webclient = new-object System.Net.WebClient;"^
+		"if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
+		"$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
+		"}"^
+		"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^
+		"}"
+    if "%MVNW_VERBOSE%" == "true" (
+        echo Finished downloading %WRAPPER_JAR%
+    )
+)
+@REM End of extension
+
+@REM Provide a "standardized" way to retrieve the CLI args that will
+@REM work with both Windows and non-Windows executions.
+set MAVEN_CMD_LINE_ARGS=%*
+
+%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
+if ERRORLEVEL 1 goto error
+goto end
+
+:error
+set ERROR_CODE=1
+
+:end
+@endlocal & set ERROR_CODE=%ERROR_CODE%
+
+if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
+@REM check for post script, once with legacy .bat ending and once with .cmd ending
+if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
+if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
+:skipRcPost
+
+@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
+if "%MAVEN_BATCH_PAUSE%" == "on" pause
+
+if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
+
+exit /B %ERROR_CODE%
diff --git a/ontologies/MetaOntologyC4I/c4i.owl b/ontologies/MetaOntologyC4I/c4i.owl
index 7341f02..37092d7 100644
--- a/ontologies/MetaOntologyC4I/c4i.owl
+++ b/ontologies/MetaOntologyC4I/c4i.owl
@@ -1,16 +1,16 @@
 <?xml version="1.0"?>
-<rdf:RDF xmlns="http://www.basys40.de/kb/c4i.owl#"
-     xml:base="http://www.basys40.de/kb/c4i.owl"
+<rdf:RDF xmlns="https://www.w3id.org/basyx/c4i#"
+     xml:base="https://www.w3id.org/basyx/c4i"
      xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
      xmlns:owl="http://www.w3.org/2002/07/owl#"
      xmlns:xml="http://www.w3.org/XML/1998/namespace"
      xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
-     xmlns:c4i="http://www.basys40.de/kb/c4i.owl#"
+     xmlns:c4i="https://www.w3id.org/basyx/c4i#"
      xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
      xmlns:foaf="http://xmlns.com/foaf/0.1/"
      xmlns:dc="http://purl.org/dc/elements/1.1/">
-    <owl:Ontology rdf:about="https://w3id.org/basyx/c4i">
-        <owl:versionIRI rdf:resource="https://w3id.org/basyx/c4i/0.0.1"/>
+    <owl:Ontology rdf:about="https://www.w3id.org/basyx/c4i">
+        <owl:versionIRI rdf:resource="https://www.w3id.org/basyx/c4i/0.0.1"/>
         <dc:contributor>
             <rdf:Description>
                 <foaf:name>Siwara Schmitt</foaf:name>
@@ -73,19 +73,19 @@
     
 
 
-    <!-- https://w3id.org/basyx/c4i#associatedWithCapability -->
+    <!-- https://www.w3id.org/basyx/c4i#associatedWithCapability -->
 
-    <owl:ObjectProperty rdf:about="https://w3id.org/basyx/c4i#associatedWithCapability">
-        <rdfs:range rdf:resource="https://w3id.org/basyx/c4i#Capability"/>
+    <owl:ObjectProperty rdf:about="https://www.w3id.org/basyx/c4i#associatedWithCapability">
+        <rdfs:range rdf:resource="https://www.w3id.org/basyx/c4i#Capability"/>
         <rdfs:comment xml:lang="en">States the existence of a relationship between a Thing and a Capability. A relationship can be that a sub sub ... part of a Thing has some capability.</rdfs:comment>
     </owl:ObjectProperty>
     
 
 
-    <!-- https://w3id.org/basyx/c4i#hasCapability -->
+    <!-- https://www.w3id.org/basyx/c4i#hasCapability -->
 
-    <owl:ObjectProperty rdf:about="https://w3id.org/basyx/c4i#hasCapability">
-        <rdfs:subPropertyOf rdf:resource="https://w3id.org/basyx/c4i#associatedWithCapability"/>
+    <owl:ObjectProperty rdf:about="https://www.w3id.org/basyx/c4i#hasCapability">
+        <rdfs:subPropertyOf rdf:resource="https://www.w3id.org/basyx/c4i#associatedWithCapability"/>
         <rdfs:comment xml:lang="en">The relation between a Thing and a Capability the Thing offers.</rdfs:comment>
     </owl:ObjectProperty>
     
@@ -102,9 +102,9 @@
     
 
 
-    <!-- https://w3id.org/basyx/c4i#Capability -->
+    <!-- https://www.w3id.org/basyx/c4i#Capability -->
 
-    <owl:Class rdf:about="https://w3id.org/basyx/c4i#Capability">
+    <owl:Class rdf:about="https://www.w3id.org/basyx/c4i#Capability">
         <rdfs:comment xml:lang="de">Ressourcenneutrales Potential einen Effekt, im Sinne eines Übergangs von einen Start- in einen Zielzustand, zu erzielen.</rdfs:comment>
         <rdfs:comment xml:lang="en">The resource neutral potential to achieve an effect, in the sense of a transition from a start to an end state.</rdfs:comment>
         <rdfs:label xml:lang="en">Capability</rdfs:label>
diff --git a/ontologies/MetaOntologyC4I/c4i2ssn.owl b/ontologies/MetaOntologyC4I/c4i2ssn.owl
index ab7423b..1f01373 100644
--- a/ontologies/MetaOntologyC4I/c4i2ssn.owl
+++ b/ontologies/MetaOntologyC4I/c4i2ssn.owl
@@ -1,6 +1,6 @@
 <?xml version="1.0"?>
-<rdf:RDF xmlns="https://w3id.org/basyx/c4i2ssn#"
-     xml:base="https://w3id.org/basyx/c4i2ssn"
+<rdf:RDF xmlns="https://www.w3id.org/basyx/c4i2ssn#"
+     xml:base="https://www.w3id.org/basyx/c4i2ssn"
      xmlns:schema="http://schema.org/"
      xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
      xmlns:terms="http://purl.org/dc/terms/"
@@ -12,9 +12,9 @@
      xmlns:vann="http://purl.org/vocab/vann/"
      xmlns:foaf="http://xmlns.com/foaf/0.1/"
      xmlns:dc="http://purl.org/dc/elements/1.1/">
-    <owl:Ontology rdf:about="https://w3id.org/basyx/c4i2ssn">
-        <owl:versionIRI rdf:resource="https://w3id.org/basyx/c4i2ssn/0.0.1"/>
-        <owl:imports rdf:resource="https://w3id.org/basyx/c4i"/>
+    <owl:Ontology rdf:about="https://www.w3id.org/basyx/c4i2ssn">
+        <owl:versionIRI rdf:resource="https://www.w3id.org/basyx/c4i2ssn/0.0.1"/>
+        <owl:imports rdf:resource="https://www.w3id.org/basyx/c4i"/>
 		
 		<dc:contributor>
             <rdf:Description>
@@ -75,28 +75,28 @@
     
 
 
-    <!-- https://w3id.org/basyx/c4i#associatedWithCapability -->
+    <!-- https://www.w3id.org/basyx/c4i#associatedWithCapability -->
 
-    <rdf:Description rdf:about="https://w3id.org/basyx/c4i#associatedWithCapability">
+    <rdf:Description rdf:about="https://www.w3id.org/basyx/c4i#associatedWithCapability">
         <owl:propertyChainAxiom rdf:parseType="Collection">
             <rdf:Description rdf:about="http://www.w3.org/ns/ssn/hasSubSystem"/>
-            <rdf:Description rdf:about="https://w3id.org/basyx/c4i#hasCapability"/>
+            <rdf:Description rdf:about="https://www.w3id.org/basyx/c4i#hasCapability"/>
         </owl:propertyChainAxiom>
     </rdf:Description>
     
 
 
-    <!-- https://w3id.org/basyx/c4i#hasCapability -->
+    <!-- https://www.w3id.org/basyx/c4i#hasCapability -->
 
-    <owl:ObjectProperty rdf:about="https://w3id.org/basyx/c4i#hasCapability">
-        <owl:equivalentProperty rdf:resource="https://w3id.org/basyx/c4i2ssn#hasSystemCapability"/>
+    <owl:ObjectProperty rdf:about="https://www.w3id.org/basyx/c4i#hasCapability">
+        <owl:equivalentProperty rdf:resource="https://www.w3id.org/basyx/c4i2ssn#hasSystemCapability"/>
     </owl:ObjectProperty>
     
 
 
-    <!-- https://w3id.org/basyx/c4i2ssn#hasSystemCapability -->
+    <!-- https://www.w3id.org/basyx/c4i2ssn#hasSystemCapability -->
 
-    <owl:ObjectProperty rdf:about="https://w3id.org/basyx/c4i2ssn#hasSystemCapability"/>
+    <owl:ObjectProperty rdf:about="https://www.w3id.org/basyx/c4i2ssn#hasSystemCapability"/>
     
 
 
@@ -117,9 +117,9 @@
     
 
 
-    <!-- https://w3id.org/basyx/c4i#Capability -->
+    <!-- https://www.w3id.org/basyx/c4i#Capability -->
 
-    <owl:Class rdf:about="https://w3id.org/basyx/c4i#Capability">
+    <owl:Class rdf:about="https://www.w3id.org/basyx/c4i#Capability">
         <owl:equivalentClass rdf:resource="http://www.w3.org/ns/ssn/systems/SystemCapability"/>
     </owl:Class>
     
diff --git a/sandbox/Java/basyx.sandbox/WebContent/META-INF/MANIFEST.MF b/sandbox/Java/basyx.sandbox/WebContent/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..59499bc
--- /dev/null
+++ b/sandbox/Java/basyx.sandbox/WebContent/META-INF/MANIFEST.MF
@@ -0,0 +1,2 @@
+Manifest-Version: 1.0
+
diff --git a/components/basys.components/basyx.components.lib/WebContent/WEB-INF/config/cfgprovider/samplecfg.properties b/sandbox/Java/basyx.sandbox/WebContent/WEB-INF/config/cfgprovider/samplecfg.properties
similarity index 100%
rename from components/basys.components/basyx.components.lib/WebContent/WEB-INF/config/cfgprovider/samplecfg.properties
rename to sandbox/Java/basyx.sandbox/WebContent/WEB-INF/config/cfgprovider/samplecfg.properties
diff --git a/components/basys.components/basyx.components.lib/WebContent/WEB-INF/config/directory/cfgdirectory/directory.properties b/sandbox/Java/basyx.sandbox/WebContent/WEB-INF/config/directory/cfgdirectory/directory.properties
similarity index 100%
rename from components/basys.components/basyx.components.lib/WebContent/WEB-INF/config/directory/cfgdirectory/directory.properties
rename to sandbox/Java/basyx.sandbox/WebContent/WEB-INF/config/directory/cfgdirectory/directory.properties
diff --git a/components/basys.components/basyx.components.lib/WebContent/WEB-INF/config/excelprovider/excelcfg.properties b/sandbox/Java/basyx.sandbox/WebContent/WEB-INF/config/excelprovider/excelcfg.properties
similarity index 100%
rename from components/basys.components/basyx.components.lib/WebContent/WEB-INF/config/excelprovider/excelcfg.properties
rename to sandbox/Java/basyx.sandbox/WebContent/WEB-INF/config/excelprovider/excelcfg.properties
diff --git a/components/basys.components/basyx.components.lib/WebContent/WEB-INF/config/excelprovider/sampledata.xlsx b/sandbox/Java/basyx.sandbox/WebContent/WEB-INF/config/excelprovider/sampledata.xlsx
similarity index 100%
rename from components/basys.components/basyx.components.lib/WebContent/WEB-INF/config/excelprovider/sampledata.xlsx
rename to sandbox/Java/basyx.sandbox/WebContent/WEB-INF/config/excelprovider/sampledata.xlsx
Binary files differ
diff --git a/components/basys.components/basyx.components.lib/WebContent/WEB-INF/config/rawcfgprovider/samplecfg.properties b/sandbox/Java/basyx.sandbox/WebContent/WEB-INF/config/rawcfgprovider/samplecfg.properties
similarity index 100%
rename from components/basys.components/basyx.components.lib/WebContent/WEB-INF/config/rawcfgprovider/samplecfg.properties
rename to sandbox/Java/basyx.sandbox/WebContent/WEB-INF/config/rawcfgprovider/samplecfg.properties
diff --git a/components/basys.components/basyx.components.lib/WebContent/WEB-INF/config/sqlprovider/sampledb.properties b/sandbox/Java/basyx.sandbox/WebContent/WEB-INF/config/sqlprovider/sampledb.properties
similarity index 100%
rename from components/basys.components/basyx.components.lib/WebContent/WEB-INF/config/sqlprovider/sampledb.properties
rename to sandbox/Java/basyx.sandbox/WebContent/WEB-INF/config/sqlprovider/sampledb.properties
diff --git a/components/basys.components/basyx.components.lib/WebContent/WEB-INF/config/xmlqueryprovider/database.xml b/sandbox/Java/basyx.sandbox/WebContent/WEB-INF/config/xmlqueryprovider/database.xml
similarity index 100%
rename from components/basys.components/basyx.components.lib/WebContent/WEB-INF/config/xmlqueryprovider/database.xml
rename to sandbox/Java/basyx.sandbox/WebContent/WEB-INF/config/xmlqueryprovider/database.xml
diff --git a/components/basys.components/basyx.components.lib/WebContent/WEB-INF/config/xmlqueryprovider/heavySensorNames.xq b/sandbox/Java/basyx.sandbox/WebContent/WEB-INF/config/xmlqueryprovider/heavySensorNames.xq
similarity index 100%
rename from components/basys.components/basyx.components.lib/WebContent/WEB-INF/config/xmlqueryprovider/heavySensorNames.xq
rename to sandbox/Java/basyx.sandbox/WebContent/WEB-INF/config/xmlqueryprovider/heavySensorNames.xq
diff --git a/components/basys.components/basyx.components.lib/WebContent/WEB-INF/config/xmlqueryprovider/xmlqueryprovider.properties b/sandbox/Java/basyx.sandbox/WebContent/WEB-INF/config/xmlqueryprovider/xmlqueryprovider.properties
similarity index 100%
rename from components/basys.components/basyx.components.lib/WebContent/WEB-INF/config/xmlqueryprovider/xmlqueryprovider.properties
rename to sandbox/Java/basyx.sandbox/WebContent/WEB-INF/config/xmlqueryprovider/xmlqueryprovider.properties
diff --git a/sandbox/Java/basyx.sandbox/WebContent/WEB-INF/web.xml b/sandbox/Java/basyx.sandbox/WebContent/WEB-INF/web.xml
new file mode 100644
index 0000000..a08f173
--- /dev/null
+++ b/sandbox/Java/basyx.sandbox/WebContent/WEB-INF/web.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1">
+  <display-name>basys.components</display-name>
+ 
+  
+  <welcome-file-list>
+    <welcome-file>index.html</welcome-file>
+    <welcome-file>index.htm</welcome-file>
+    <welcome-file>index.jsp</welcome-file>
+    <welcome-file>default.html</welcome-file>
+    <welcome-file>default.htm</welcome-file>
+    <welcome-file>default.jsp</welcome-file>
+  </welcome-file-list>
+</web-app>
\ No newline at end of file
diff --git a/sandbox/Java/basyx.sandbox/pom.xml b/sandbox/Java/basyx.sandbox/pom.xml
index 2783d41..4970b82 100644
--- a/sandbox/Java/basyx.sandbox/pom.xml
+++ b/sandbox/Java/basyx.sandbox/pom.xml
@@ -5,7 +5,7 @@
 
 	<groupId>org.eclipse.basyx</groupId>
 	<artifactId>basyx.sandbox</artifactId>
-	<version>0.0.1-SNAPSHOT</version>
+	<version>0.1.0-SNAPSHOT</version>
 	<packaging>jar</packaging>
 
 	<name>basyx.sandbox</name>
@@ -42,21 +42,21 @@
 		<dependency>
 			<groupId>org.eclipse.basyx</groupId>
 			<artifactId>basyx.components.lib</artifactId>
-			<version>0.0.1-SNAPSHOT</version>
+			<version>0.1.0-SNAPSHOT</version>
 		</dependency>
 
 		<!-- Add explicit SQLRegistry dependency -->
 		<dependency>
 			<groupId>org.eclipse.basyx</groupId>
 			<artifactId>basyx.components.sqlregistry</artifactId>
-			<version>0.0.1-SNAPSHOT</version>
+			<version>0.1.0-SNAPSHOT</version>
 		</dependency>
 
 		<!-- Adds additional classes of the BaSys SDK for tests -->
 		<dependency>
 			<groupId>org.eclipse.basyx</groupId>
 			<artifactId>basyx.sdk</artifactId>
-			<version>0.0.1-SNAPSHOT</version>
+			<version>0.1.0-SNAPSHOT</version>
 			<classifier>tests</classifier>
 			<scope>test</scope>
 		</dependency>
diff --git a/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/cfgprovider/CFGSubModelProvider.java b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/cfgprovider/CFGSubModelProvider.java
new file mode 100644
index 0000000..e26dc5e
--- /dev/null
+++ b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/cfgprovider/CFGSubModelProvider.java
@@ -0,0 +1,44 @@
+package org.eclipse.basyx.sandbox.components.cfgprovider;
+
+import java.util.Map;
+
+import org.eclipse.basyx.components.provider.BaseConfiguredProvider;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElement;
+import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+
+/**
+ * Asset administration shell sub model provider that exports a properties file
+ * 
+ * @author kuhn
+ *
+ */
+public class CFGSubModelProvider extends BaseConfiguredProvider {
+
+	/**
+	 * Initiates a logger using the current class
+	 */
+	private static final Logger logger = LoggerFactory.getLogger(CFGSubModelProvider.class);
+
+	/**
+	 * Constructor
+	 */
+	public CFGSubModelProvider(Map<Object, Object> cfgValues) {
+		// Call base constructor
+		super(cfgValues);
+
+		// Add properties
+		for (String key: getConfiguredProperties(cfgValues)) {
+			// Create properties
+			SubmodelElement elem = createSubmodelElement(key, cfgValues.get(key), cfgValues);
+			createValue("submodel/" + SubmodelElementProvider.ELEMENTS, elem);
+			
+			// Debug output
+			logger.debug("Adding configured property: "+key.toString()+" = "+cfgValues.get(key));
+		}
+	}
+}
+
diff --git a/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/cfgprovider/RawCFGSubModelProvider.java b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/cfgprovider/RawCFGSubModelProvider.java
new file mode 100644
index 0000000..4d4a2c3
--- /dev/null
+++ b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/cfgprovider/RawCFGSubModelProvider.java
@@ -0,0 +1,81 @@
+package org.eclipse.basyx.sandbox.components.cfgprovider;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.basyx.components.provider.BaseConfiguredProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Asset administration shell sub model provider that exports a properties file
+ * 
+ * @author kuhn
+ *
+ */
+public class RawCFGSubModelProvider extends BaseConfiguredProvider {
+	
+	/**
+	 * Initiates a logger using the current class
+	 */
+	private static final Logger logger = LoggerFactory.getLogger(RawCFGSubModelProvider.class);
+
+	private static final String FTYPE = "$ftype";
+
+	/**
+	 * Constructor
+	 */
+	@SuppressWarnings("unchecked")
+	public RawCFGSubModelProvider(Map<Object, Object> cfgValues) {
+		// Call base constructor -> creates base submodelData from cfgValues
+		super(cfgValues);
+
+		// Load properties
+		for (Object key : cfgValues.keySet()) {
+			// Do not put meta data keys into map
+			if (((String) key).endsWith(FTYPE))
+				continue;
+
+			// Get path to element
+			String[] path = splitPath((String) key);
+
+			// Create path
+			Map<String, Object> scope = new HashMap<>();
+			scope = submodelData;
+			for (int i = 0; i < path.length - 1; i++) {
+				if (!scope.containsKey(path[i]))
+					scope.put(path[i], new HashMap<String, Object>());
+				scope = (Map<String, Object>) scope.get(path[i]);
+			}
+
+			// Get and optionally convert value
+			Object value = cfgValues.get(key);
+			// - Cast value if requested by user
+			if (cfgValues.get(key + FTYPE) != null)
+				switch ((String) cfgValues.get(key + FTYPE)) {
+				case "int":
+					value = Integer.parseInt((String) value);
+					break;
+				case "boolean":
+					value = Boolean.parseBoolean((String) value);
+					break;
+				case "float":
+					value = Float.parseFloat((String) value);
+					break;
+
+				default:
+					logger.error("Unknown type:" + cfgValues.get(key + FTYPE));
+				}
+
+			logger.debug("Putting:" + key + " = " + cfgValues.get(key) + " as " + value.getClass().getName());
+
+			scope.put(path[path.length - 1], value);
+		}
+
+		// Push data to provider
+		setSubmodel(submodelData);
+
+		// Print configuration values
+		logger.debug("CFG exported");
+	}
+}
diff --git a/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/cfgprovider/servlet/AbstractCFGSubModelProviderServlet.java b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/cfgprovider/servlet/AbstractCFGSubModelProviderServlet.java
new file mode 100644
index 0000000..7198b6d
--- /dev/null
+++ b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/cfgprovider/servlet/AbstractCFGSubModelProviderServlet.java
@@ -0,0 +1,113 @@
+package org.eclipse.basyx.sandbox.components.cfgprovider.servlet;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+
+import javax.servlet.ServletException;
+
+import org.eclipse.basyx.aas.restapi.VABMultiSubmodelProvider;
+import org.eclipse.basyx.submodel.restapi.SubModelProvider;
+import org.eclipse.basyx.vab.protocol.http.server.VABHTTPInterface;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Abstract super class for all config file using submodel provider servlets
+ * 
+ * @author schnicke
+ *
+ */
+public abstract class AbstractCFGSubModelProviderServlet extends VABHTTPInterface<VABMultiSubmodelProvider> {
+	
+	/**
+	 * Initiates a logger using the current class
+	 */
+	private static final Logger logger = LoggerFactory.getLogger(AbstractCFGSubModelProviderServlet.class);
+	
+	/**
+	 * Version information to identify the version of serialized instances
+	 */
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * Store ID of the sub model provided by this provider
+	 */
+	protected String submodelID = null;
+
+	/**
+	 * Configuration properties
+	 */
+	protected Properties properties = null;
+
+
+	/**
+	 * Standard constructor creating a servlet containing a new
+	 * VABMultiSubmodelProvider()
+	 */
+	public AbstractCFGSubModelProviderServlet() {
+		super(new VABMultiSubmodelProvider());
+	}
+
+	/**
+	 * Load properties from file
+	 */
+	protected void loadProperties(String cfgFilePath) {
+		// Read property file
+		try {
+			// Open property file
+			InputStream input = getServletContext().getResourceAsStream(cfgFilePath);
+
+			// Instantiate property structure
+			properties = new Properties();
+			properties.load(input);
+
+			// Extract AAS properties
+			this.submodelID = properties.getProperty(getSubmodelId());
+		} catch (IOException e) {
+			// Output exception
+			e.printStackTrace();
+		}
+	}
+
+	/**
+	 * Initialize servlet
+	 * 
+	 * @throws ServletException
+	 */
+	@Override
+	public void init() throws ServletException {
+		// Call base implementation
+		super.init();
+
+		// Read configuration values
+		String configFilePath = getInitParameter("config");
+		// - Read property file
+		loadProperties(configFilePath);
+		
+		logger.debug("1:" + submodelID);
+
+		// Create sub model provider
+		SubModelProvider submodelProvider = createProvider(properties);
+		// - Add sub model provider
+		this.getModelProvider().addSubmodel(submodelID, submodelProvider);
+
+		logger.debug("CFG file loaded");
+	}
+
+	/**
+	 * Retrieves the submodel id
+	 * 
+	 * @return
+	 */
+	protected abstract String getSubmodelId();
+
+	/**
+	 * Creates the appropriate provider based on the passed properties
+	 * 
+	 * @param properties
+	 * @return
+	 */
+	protected abstract SubModelProvider createProvider(Properties properties);
+
+}
diff --git a/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/cfgprovider/servlet/CFGSubModelProviderServlet.java b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/cfgprovider/servlet/CFGSubModelProviderServlet.java
new file mode 100644
index 0000000..be1b334
--- /dev/null
+++ b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/cfgprovider/servlet/CFGSubModelProviderServlet.java
@@ -0,0 +1,32 @@
+package org.eclipse.basyx.sandbox.components.cfgprovider.servlet;
+
+import java.util.Properties;
+
+import org.eclipse.basyx.components.provider.BaseConfiguredProvider;
+import org.eclipse.basyx.sandbox.components.cfgprovider.CFGSubModelProvider;
+import org.eclipse.basyx.submodel.restapi.SubModelProvider;
+
+/**
+ * Servlet interface for configuration file sub model provider
+ * 
+ * @author kuhn
+ *
+ */
+public class CFGSubModelProviderServlet extends AbstractCFGSubModelProviderServlet {
+
+	/**
+	 * Version information to identify the version of serialized instances
+	 */
+	private static final long serialVersionUID = -7525848804623194574L;
+
+
+	@Override
+	protected String getSubmodelId() {
+		return BaseConfiguredProvider.buildBasyxCfgName(BaseConfiguredProvider.SUBMODELID);
+	}
+
+	@Override
+	protected SubModelProvider createProvider(Properties properties) {
+		return new CFGSubModelProvider(properties);
+	}
+}
diff --git a/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/cfgprovider/servlet/RawCFGSubModelProviderServlet.java b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/cfgprovider/servlet/RawCFGSubModelProviderServlet.java
new file mode 100644
index 0000000..0087b4c
--- /dev/null
+++ b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/cfgprovider/servlet/RawCFGSubModelProviderServlet.java
@@ -0,0 +1,33 @@
+package org.eclipse.basyx.sandbox.components.cfgprovider.servlet;
+
+import java.util.Properties;
+
+import org.eclipse.basyx.sandbox.components.cfgprovider.RawCFGSubModelProvider;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
+import org.eclipse.basyx.submodel.restapi.SubModelProvider;
+
+/**
+ * Servlet interface for configuration file sub model provider
+ * 
+ * @author kuhn
+ *
+ */
+public class RawCFGSubModelProviderServlet extends AbstractCFGSubModelProviderServlet {
+
+	/**
+	 * Version information to identify the version of serialized instances
+	 */
+	private static final long serialVersionUID = -8132051635222485719L;
+
+
+	@Override
+	protected String getSubmodelId() {
+		return Referable.IDSHORT;
+	}
+
+
+	@Override
+	protected SubModelProvider createProvider(Properties properties) {
+		return new RawCFGSubModelProvider(properties);
+	}
+}
diff --git a/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/registry/AASDirectoryEntry.java b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/registry/AASDirectoryEntry.java
new file mode 100644
index 0000000..34fdbdb
--- /dev/null
+++ b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/registry/AASDirectoryEntry.java
@@ -0,0 +1,375 @@
+package org.eclipse.basyx.sandbox.components.registry;
+
+import java.util.Collection;
+import java.util.HashSet;
+
+import org.eclipse.basyx.sandbox.components.registry.exception.AASDirectoryFormatException;
+
+
+
+/**
+ * Asset Administration Shell or sub model directory entry
+ * 
+ * IDs usually are formed as URIs: urn:<legalBody>:<SubUnit>:<Submodel>:<version>:<revision>:<elementID>#<instance>
+ * 
+ * @author kuhn
+ *
+ */
+public class AASDirectoryEntry {
+
+	
+	/**
+	 * Indicate undefined AAS content type
+	 */
+	public static final int AAS_CONTENTTYPE_UNDEFINED = -1;
+
+	
+	/**
+	 * Indicate local AAS content type. The serialized AAS is stored in the content property of this class. 
+	 */
+	public static final int AAS_CONTENTTYPE_LOCAL = 1;
+
+	
+	/**
+	 * Indicate remote AAS content type. The content property of this class contains a URL that points to the directory service. 
+	 */
+	public static final int AAS_CONTENTTYPE_REMOTE = 2;
+
+	
+	/**
+	 * Indicate proxy AAS content type. The content property of this class contains an ID (specified as URI) that points to the
+	 * AAS entry that all requests should be forwarded to. 
+	 */
+	public static final int AAS_CONTENTTYPE_PROXY = 3;
+
+	
+	
+	
+	
+	/**
+	 * Store the AAS ID
+	 */
+	protected String id = null;
+	
+	
+	/**
+	 * Store the AAS content
+	 */
+	protected String content = null;
+	
+	
+	/**
+	 * Store the AAS content type (local, remote, or proxy)
+	 * 
+	 * Local AAS content means that the AAS is serialized in the content property. Remote indicates
+	 * that the content property contains a URL that points to the AAS. Proxy indicates that the
+	 * content contains another AAS ID, to which requests will be forwarded. 
+	 */
+	protected int contentType = -1;
+	
+	
+	/**
+	 * Store the tags for this AAS
+	 */
+	protected HashSet<String> tags = new HashSet<>();
+	
+	
+	
+	
+	
+	/**
+	 * Constructor
+	 */
+	public AASDirectoryEntry(String aasId, String aasContent, String aasContentType, String aasTags) {
+		// Store AAS parameter
+		id      = aasId;
+		content = aasContent;
+		
+		
+		// Try to process AAS content type
+		try {
+			// Store AAS content type
+			switch(aasContentType.toLowerCase()) {
+				case "local":  contentType = AAS_CONTENTTYPE_LOCAL; break;
+				case "remote": contentType = AAS_CONTENTTYPE_REMOTE; break;
+				case "proxy":  contentType = AAS_CONTENTTYPE_PROXY; break;
+
+				default: throw new AASDirectoryFormatException("Unknown content type: "+aasContentType);
+			}
+		} catch (NullPointerException e) {
+			// Assume local AAS for undefined AAS types
+			contentType = AAS_CONTENTTYPE_LOCAL;
+		}
+		
+		
+		// Try to Store AAS tags
+		try {
+			String[] splitTags = aasTags.split(",");
+			// - Only add non-empty tags
+			for (String tag: splitTags) if (tag.trim().length() > 0) tags.add(tag.trim());
+		} catch (NullPointerException e) {
+			// Accept AAS without tags
+		}		
+	}
+	
+	
+	/**
+	 * Check if ID is a valid URI. A valid URI starts with "urn:" prefix and defines at least a legal body.
+	 */
+	public boolean isValidID() {
+		return (id.startsWith("urn"));
+	}
+
+	
+	/**
+	 * Check if ID contains a legal entity
+	 */
+	public boolean hasLegalEntity() {
+		// Split ID by ':' token
+		String[] idParts = id.split(":");
+		
+		// Check if subunit is defined
+		if (idParts.length < 2) return false;
+		
+		// Check if any information is contained in subunit field
+		return (idParts[1].trim().length() > 0);
+	}
+
+	
+	/**
+	 * Return the legal entity of this AAS
+	 */
+	public String getLegalEntity() {
+		// Split ID by ':' token
+		String[] idParts = id.split(":");
+		
+		// Return legal Entity part
+		return idParts[1];
+	}
+	
+	
+	/**
+	 * Check if AAS legal entity is of type (ends with given suffix, e.g. ".fraunhofer.de")
+	 */
+	public boolean isLegalEntityOf(String suffix) {
+		return getLegalEntity().endsWith(suffix);
+	}
+	
+	
+	/**
+	 * Check if ID contains a subunit
+	 */
+	public boolean hasSubUnit() {
+		// Split ID by ':' token
+		String[] idParts = id.split(":");
+		
+		// Check if subunit is defined
+		if (idParts.length < 3) return false;
+		
+		// Check if any information is contained in subunit field
+		return (idParts[2].trim().length() > 0);
+	}
+	
+	
+	/**
+	 * Get the subunit of the ID field
+	 */
+	public String getSubUnit() {
+		// Split ID by ':' token
+		String[] idParts = id.split(":");
+		
+		// Check if subunit is defined
+		if (idParts.length < 3) return null;
+		
+		// Check if any information is contained in subunit field
+		return idParts[2].trim();
+	}
+
+	
+	/**
+	 * Check if ID contains a sub model
+	 */
+	public boolean hasSubModel() {
+		// Split ID by ':' token
+		String[] idParts = id.split(":");
+		
+		// Check if subunit is defined
+		if (idParts.length < 4) return false;
+		
+		// Check if any information is contained in subunit field
+		return (idParts[3].trim().length() > 0);
+	}
+	
+	
+	/**
+	 * Get the sub model of the ID field
+	 */
+	public String getSubModel() {
+		// Split ID by ':' token
+		String[] idParts = id.split(":");
+		
+		// Check if subunit is defined
+		if (idParts.length < 4) return null;
+		
+		// Check if any information is contained in subunit field
+		return idParts[3].trim();
+	}
+
+	
+	/**
+	 * Check if ID contains a version
+	 */
+	public boolean hasVersion() {
+		// Split ID by ':' token
+		String[] idParts = id.split(":");
+		
+		// Check if subunit is defined
+		if (idParts.length < 5) return false;
+		
+		// Check if any information is contained in subunit field
+		return (idParts[4].trim().length() > 0);
+	}
+
+	
+	/**
+	 * Get AAS version
+	 */
+	public String getVersion() {
+		// Split ID by ':' token
+		String[] idParts = id.split(":");
+		
+		// Check if subunit is defined
+		if (idParts.length < 5) return null;
+		
+		// Check if any information is contained in subunit field
+		return idParts[4].trim();
+	}
+
+	
+	/**
+	 * Check if ID contains a revision
+	 */
+	public boolean hasRevision() {
+		// Split ID by ':' token
+		String[] idParts = id.split(":");
+		
+		// Check if subunit is defined
+		if (idParts.length < 6) return false;
+		
+		// Check if any information is contained in subunit field
+		return (idParts[5].trim().length() > 0);
+	}
+
+	
+	/**
+	 * Get AAS revision
+	 */
+	public String getRevision() {
+		// Split ID by ':' token
+		String[] idParts = id.split(":");
+		
+		// Check if subunit is defined
+		if (idParts.length < 6) return null;
+		
+		// Check if any information is contained in subunit field
+		return idParts[5].trim();
+	}
+	
+	
+	/**
+	 * Check if ID contains an element ID
+	 */
+	public boolean hasElementID() {
+		// Split ID by ':' token
+		String[] idParts = id.split(":");
+		
+		// Check if subunit is defined
+		if (idParts.length < 7) return false;
+		
+		// Remove element instance if an instance is defined
+		if (idParts[6].indexOf('#') > -1) idParts[6]=idParts[6].substring(0, idParts[6].indexOf('#'));
+		// Check if any information is contained in subunit field
+		return (idParts[6].trim().length() > 0);
+	}
+
+	
+	/**
+	 * Get element ID
+	 */
+	public String getElementID() {
+		// Split ID by ':' token
+		String[] idParts = id.split(":");
+		
+		// Check if subunit is defined
+		if (idParts.length < 7) return null;
+		
+		// Remove element instance if an instance is defined
+		if (idParts[6].indexOf('#') > -1) idParts[6]=idParts[6].substring(0, idParts[6].indexOf('#'));
+		// Check if any information is contained in subunit field
+		return idParts[6].trim();
+	}
+
+	
+	/**
+	 * Check if ID contains an instance
+	 */
+	public boolean hasElementInstance() {
+		// Split ID by ':' token
+		String[] idParts = id.split(":");
+		
+		// Check if subunit is defined
+		if (idParts.length < 7) return false;
+		
+		// Remove element instance if an instance is defined
+		if (idParts[6].indexOf('#') > -1) idParts[6]=idParts[6].substring(idParts[6].indexOf('#'));
+		// Check if any information is contained in subunit field
+		return (idParts[6].trim().length() > 0);
+	}
+
+
+	/**
+	 * Get instance ID
+	 */
+	public String getElementInstance() {
+		// Catch all exceptions 
+		try {
+			// Split ID by ':' token
+			String[] idParts = id.split(":");
+
+			// Check if subunit is defined
+			if (idParts.length < 7) return null;
+
+			// Remove element instance if an instance is defined
+			if (idParts[6].indexOf('#') > -1) idParts[6]=idParts[6].substring(idParts[6].indexOf('#')+1);
+			
+			// Check if any information is contained in subunit field
+			return idParts[6].trim();
+		} catch (Exception e) {
+			return null;
+		}
+	}
+	
+	
+	/**
+	 * Get AAS content
+	 */
+	public String getAASContent() {
+		return content;
+	}
+	
+	
+	/**
+	 * Get AAS content type
+	 */
+	public int getAASContentType() {
+		return contentType;
+	}
+	
+	
+	/**
+	 * Get AAS tags
+	 */
+	public Collection<String> getAASTags() {
+		return tags;
+	}
+}
diff --git a/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/registry/StaticCFGDirectoryServlet.java b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/registry/StaticCFGDirectoryServlet.java
new file mode 100644
index 0000000..db4f329
--- /dev/null
+++ b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/registry/StaticCFGDirectoryServlet.java
@@ -0,0 +1,453 @@
+package org.eclipse.basyx.sandbox.components.registry;
+
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URLDecoder;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.basyx.sandbox.components.registry.exception.AASDirectoryProviderException;
+import org.eclipse.basyx.vab.protocol.http.server.BasysHTTPServlet;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+
+
+/**
+ * Static configuration file based directory provider
+ * 
+ * This directory provider provides a static directory. It therefore only supports get() operations. 
+ * Modification of the directory via PUT/POST/PATCH/DELETE operations is not supported.
+ * 
+ * @author kuhn
+ *
+ */
+public class StaticCFGDirectoryServlet extends BasysHTTPServlet {
+	
+	/**
+	 * Initiates a logger using the current class
+	 */
+	private static final Logger logger = LoggerFactory.getLogger(StaticCFGDirectoryServlet.class);
+
+	
+	/**
+	 * Version information to identify the version of serialized instances
+	 */
+	private static final long serialVersionUID = 1L;
+
+	
+
+	/**
+	 * Configuration properties (raw input from file)
+	 */
+	protected Properties properties = null;
+	
+	
+	/**
+	 * Asset administration shells by ID
+	 */
+	protected Map<String, AASDirectoryEntry> aasByID = new HashMap<>();
+	
+	
+	/**
+	 * Asset administration shells by tag
+	 */
+	protected Map<String, Collection<AASDirectoryEntry>> aasByTag = new HashMap<>();
+	
+	
+	/**
+	 * Uplink server
+	 */
+	protected String uplink = null;
+	
+	
+	/**
+	 * Downlink servers
+	 */
+	protected Map<String, String> downlinks = new HashMap<>();
+	
+	
+	
+	
+	
+	/**
+	 * Constructor
+	 */
+	public StaticCFGDirectoryServlet() {
+		// Invoke base constructor
+		super();
+	}
+	
+	/**
+	 * Adds init parameter to servlet
+	 */
+	@Override
+	public String getInitParameter(String name) {
+
+		if (name.equals("config")) return "/WebContent/WEB-INF/config/directory/cfgdirectory/directory.properties";
+		
+		return null;
+	}
+	
+	/**
+	 * Load a property
+	 */
+	protected String extractProperty(Properties prop, String key) {
+		// Check if properties contain value
+		if (!prop.containsKey(key)) return null;
+		
+		// Extract and remove value
+		String value = (String) prop.get(key);
+		prop.remove(key);
+		
+		// Return value
+		return value;
+	}
+	
+	
+	
+	/**
+	 * Extract property keys with prefix and suffix. Prefix and suffix is removed from key.
+	 */
+	protected Collection<String> getProperties(Properties prop, String prefix, String suffix) {
+		// Store result
+		HashSet<String> result = new HashSet<>();
+		
+		// Iterate keys
+		for (String key: prop.stringPropertyNames()) {
+			if (key.startsWith(prefix) && key.endsWith(suffix)) result.add(key.substring(prefix.length(), key.length()-suffix.length()));
+		}
+		
+		// Return result
+		return result;
+	}
+	
+	
+	
+	/**
+	 * Extract downlink servers
+	 */
+	protected Map<String, String> extractDownlinks(Properties prop) {
+		// Return value
+		Map<String, String> result = new HashMap<>();
+		
+		// Downlink server names
+		Collection<String> downlinkServerNames = getProperties(prop, "cfg.downlink.", ".pattern");
+		
+		// Remove downlink pattern and server URL
+		for (String name: downlinkServerNames) {
+			// Get downlink pattern and server URL
+			result.put(prop.getProperty("cfg.downlink."+name+".pattern"), prop.getProperty("cfg.downlink."+name+".directory"));
+			// Remove pattern and directory properties
+			prop.remove("cfg.downlink."+name+".pattern");
+			prop.remove("cfg.downlink."+name+".directory");
+		}
+		
+		// Return downlink server mappings
+		return result;
+	}
+	
+	
+	
+	/**
+	 * Extract Asset Administration Shell definitions
+	 */
+	protected Map<String, AASDirectoryEntry> extractAAS(Properties prop) {
+		// Return value
+		Map<String, AASDirectoryEntry> result = new HashMap<>();
+		
+		// Get AAS IDs
+		Collection<String> aasIDs = getProperties(prop, "", ".id");
+		
+		// Create AAS directory entries from properties
+		for (String aasID : aasIDs) {
+			// Create AAS directory entry
+			AASDirectoryEntry entry = new AASDirectoryEntry(prop.getProperty(aasID+".id"), prop.getProperty(aasID+".aas"), prop.getProperty(aasID+".type"), prop.getProperty(aasID+".tags"));
+			
+			// Add AAS directory entry
+			result.put(prop.getProperty(aasID+".id"), entry);
+		}
+		
+		// Return ID to AAS mappings
+		return result;
+	}
+	
+	
+	
+	/**
+	 * Map AAS tags to AAS
+	 */
+	protected Map<String, Collection<AASDirectoryEntry>> mapAASToTags(Map<String, AASDirectoryEntry> aasByID) {
+		// Return value
+		Map<String, Collection<AASDirectoryEntry>> result = new HashMap<>();
+		
+		// Iterate AAS directory entries
+		for (AASDirectoryEntry dirEntry: aasByID.values()) {
+			// Process tags
+			for (String tag: dirEntry.getAASTags()) {
+				// Create tag if necessary
+				if (!result.containsKey(tag)) {result.put(tag, new HashSet<AASDirectoryEntry>());}
+				
+				// Add AAS to tag
+				result.get(tag).add(dirEntry);
+			}
+		}
+		
+		// Return HashTag to AAS mappings
+		return result;
+	}
+	
+	
+	
+	/**
+	 * Load properties from file
+	 */
+	protected void loadProperties(String cfgFilePath) {
+		// Read property file
+		try {
+			// Open property file
+			InputStream input = getServletContext().getResourceAsStream(cfgFilePath); 
+
+			// Instantiate property structure
+			properties = new Properties();
+			properties.load(input);
+			
+			logger.debug("properties:"+properties);
+			logger.debug("properties (keys):"+properties.keySet());
+			logger.debug("properties (cfg.downlink.is.pattern):"+properties.get("cfg.downlink.is.pattern"));
+			
+			// Process properties
+			// - Uplink server
+			uplink = extractProperty(properties, "cfg.uplink");
+			// - Downlink servers
+			downlinks = extractDownlinks(properties);
+			// - AAS by ID
+			aasByID = extractAAS(properties);
+			// - AAS by tag
+			aasByTag = mapAASToTags(aasByID);
+			
+			logger.debug("Downlink:"+downlinks);
+			logger.debug("properties:"+properties);
+			logger.debug("aasbyID:"+aasByID);
+			
+		} catch (IOException e) {
+			// Output exception
+			e.printStackTrace();
+		}		
+	}
+
+
+
+	/**
+	 * Initialize servlet
+	 * 
+	 * @throws ServletException 
+	 */
+	@Override
+	public void init() throws ServletException {
+		// Call base implementation
+		super.init();
+		
+		// Read configuration values
+		String configFilePath = getInitParameter("config");
+		// - Read property file
+		loadProperties(configFilePath);
+	}
+	
+	
+	/**
+	 * Get AAS content from AASDirectoryEntry
+	 */
+	protected String getAASContent(AASDirectoryEntry directoryEntry) {
+		// Process directory entry
+		switch (directoryEntry.getAASContentType()) {
+
+			// Local content type
+			case AASDirectoryEntry.AAS_CONTENTTYPE_LOCAL:
+				return directoryEntry.getAASContent();
+
+			// Remote content type
+			case AASDirectoryEntry.AAS_CONTENTTYPE_REMOTE:
+				throw new AASDirectoryProviderException("Unsupported AAS content type");
+
+			// Proxy content type - content is ID of AAS that contains the information
+			case AASDirectoryEntry.AAS_CONTENTTYPE_PROXY:
+				return getAASContentByID(directoryEntry.getAASContent());
+
+			// Unknown content type
+			default:
+				throw new AASDirectoryProviderException("Unknown AAS content type");
+		}
+	}
+	
+	
+	
+	/**
+	 * Get requested tags as collection
+	 */
+	protected Collection<String> getTagsAsCollection(String tags) {
+		// Collection stores AAS tags
+		Collection<String> alltags = new HashSet<>();
+		
+		// Catch null pointer exceptions
+		try {
+			// Get AAS tags
+			String[] splitTags  = tags.split(",");
+
+			// Only add non-empty tags
+			for (String tag: splitTags) if (tag.trim().length() > 0) alltags.add(tag.trim());
+		} catch (NullPointerException e) {}
+
+		// Return all tags
+		return alltags;
+	}
+	
+	
+	
+	/**
+	 * Get a specific AAS content with ID
+	 */
+	protected String getAASContentByID(String aasID) {
+		// Extract requested AAS ID
+		AASDirectoryEntry aas = aasByID.get(aasID);
+		
+		// Null pointer check
+		if (aas == null)
+			return null;
+		
+		// Return result
+		return getAASContent(aas);
+	}
+	
+	
+	
+	
+	
+	/**
+	 * Implement "Get" operation 
+	 * 
+	 * Process HTTP get request - get sub model property value
+	 */
+	@Override
+	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+		// Process request depending on the path and on parameter
+		String uri 			= req.getRequestURI();
+		String contextPath  = req.getContextPath();
+		String path 		= URLDecoder.decode(uri.substring(contextPath.length()+1).substring(req.getServletPath().length()), "UTF-8"); // plus 1 for "/"
+				
+		// Extract action parameter
+		Collection<String> alltags = getTagsAsCollection(req.getParameter("tags"));
+		
+		
+		// Setup HTML response header
+		resp.setContentType("application/json");
+		resp.setCharacterEncoding("UTF-8");
+
+		
+		// Process get request
+		// - Get all (local) AAS
+		if (path.equals("api/v1/registry")) {
+			// Extract AAS directory entries
+			Collection<AASDirectoryEntry> entries = null;
+
+			// Check if tags are to be processed
+			if (alltags.isEmpty()) {
+				// Get all tags
+				entries = aasByID.values();
+			} else {
+				// HashSet that holds all elements
+				Set<AASDirectoryEntry> taggedEntries = new HashSet<>();
+				
+				// Get tagged elements that have all requested tags
+				// - Get first requested tag
+				taggedEntries.addAll(aasByTag.get(alltags.iterator().next()));
+				// - Remove all directory entries that do not have all tags
+				for (String tag: alltags) taggedEntries.retainAll(aasByTag.get(tag));
+				// - Place remaining elements into entries collection
+				entries = taggedEntries;
+			}
+			
+			// Build response string
+			StringBuilder response = new StringBuilder();
+			for (AASDirectoryEntry entry: entries) response.append(getAASContent(entry));
+
+			// Write result
+			sendResponse(response.toString(), resp.getWriter());
+			// End processing
+			return;
+		}
+		// Get a specific AAS
+		else if (path.startsWith("api/v1/registry/")) {
+			logger.debug("Getting:"+path);
+			
+			// Get requested AAS with ID
+			String aas = getAASContentByID(path.substring(new String("api/v1/registry/").length()));
+			
+			// Write result
+			sendResponse(aas, resp.getWriter());
+			// End processing
+			return;
+		} else {
+			// Send null response for unknown path
+			sendResponse(null, resp.getWriter());
+			return;
+		}
+	}
+
+	
+	
+	/**
+	 * Implement "Put" operation
+	 */
+	@Override
+	protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+		// Indicate an unsupported operation
+		resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, "Request not implemented for this service");
+	}
+
+
+	
+	/**
+	 * <pre>
+	 * Handle HTTP POST operation. Creates a new Property, Operation, Event, Submodel or AAS or invokes an operation.
+	 */
+	@Override
+	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+		// Indicate an unsupported operation
+		resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, "Request not implemented for this service");
+	}
+
+
+	
+	/**
+	 * Handle a HTTP PATCH operation. Updates a map or collection respective to action string.
+	 * 
+	 */
+	@Override
+	protected void doPatch(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+		// Indicate an unsupported operation
+		resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, "Request not implemented for this service");
+	}
+	 
+
+	
+	 /**
+	 * Implement "Delete" operation.  Deletes any resource under the given path.
+	 */
+	@Override
+	protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+		// Indicate an unsupported operation
+		resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, "Request not implemented for this service");
+	}
+}
+
diff --git a/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/registry/exception/AASDirectoryFormatException.java b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/registry/exception/AASDirectoryFormatException.java
new file mode 100644
index 0000000..93e57a6
--- /dev/null
+++ b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/registry/exception/AASDirectoryFormatException.java
@@ -0,0 +1,36 @@
+package org.eclipse.basyx.sandbox.components.registry.exception;
+
+
+
+
+/**
+ * Indicate a problem with the AAS directory format
+ * 
+ * @author kuhn
+ *
+ */
+public class AASDirectoryFormatException extends RuntimeException {
+
+	
+	/**
+	 * Version number support for serialized instances
+	 */
+	private static final long serialVersionUID = 1L;
+
+	
+	/**
+	 * Error message
+	 */
+	protected String errorMessage = null;
+	
+	
+	
+	
+	/**
+	 * Constructor
+	 */
+	public AASDirectoryFormatException(String errorMsg) {
+		errorMessage = errorMsg;
+	}
+}
+
diff --git a/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/registry/exception/AASDirectoryProviderException.java b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/registry/exception/AASDirectoryProviderException.java
new file mode 100644
index 0000000..ade137b
--- /dev/null
+++ b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/registry/exception/AASDirectoryProviderException.java
@@ -0,0 +1,36 @@
+package org.eclipse.basyx.sandbox.components.registry.exception;
+
+
+
+
+/**
+ * Indicate a problem with the AAS directory provider
+ * 
+ * @author kuhn
+ *
+ */
+public class AASDirectoryProviderException extends RuntimeException {
+
+	
+	/**
+	 * Version number support for serialized instances
+	 */
+	private static final long serialVersionUID = 1L;
+
+	
+	/**
+	 * Error message
+	 */
+	protected String errorMessage = null;
+	
+	
+	
+	
+	/**
+	 * Constructor
+	 */
+	public AASDirectoryProviderException(String errorMsg) {
+		errorMessage = errorMsg;
+	}
+}
+
diff --git a/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/sqlprovider/SQLPreconfiguredSubModelProvider.java b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/sqlprovider/SQLPreconfiguredSubModelProvider.java
new file mode 100644
index 0000000..4360636
--- /dev/null
+++ b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/sqlprovider/SQLPreconfiguredSubModelProvider.java
@@ -0,0 +1,518 @@
+package org.eclipse.basyx.sandbox.components.sqlprovider;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+
+import org.eclipse.basyx.components.provider.BaseConfiguredProvider;
+import org.eclipse.basyx.tools.sql.driver.SQLDriver;
+import org.eclipse.basyx.tools.sql.query.DynamicSQLQuery;
+import org.eclipse.basyx.tools.sql.query.DynamicSQLRunner;
+import org.eclipse.basyx.tools.sql.query.DynamicSQLUpdate;
+import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaHandler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+
+
+/**
+ * Asset administration shell sub model provider that connects to SQL database
+ * 
+ * @author kuhn
+ *
+ */
+public class SQLPreconfiguredSubModelProvider extends BaseConfiguredProvider {
+	
+	/**
+	 * Initiates a logger using the current class
+	 */
+	private static final Logger logger = LoggerFactory.getLogger(SQLPreconfiguredSubModelProvider.class);
+	
+	/**
+	 * SQL database user name
+	 */
+	protected String sqlUser = null;
+
+	/**
+	 * SQL database password
+	 */
+	protected String sqlPass = null;
+	
+	/**
+	 * SQL database path
+	 */
+	protected String sqlURL  = null;
+
+	
+	
+	/**
+	 * SQL database driver
+	 */
+	protected String sqlDriver = null;
+	
+	/**
+	 * SQL database query prefix
+	 */
+	protected String sqlPrefix = null;
+	
+	
+	
+	/**
+	 * SQL property connections
+	 */
+	protected Set<String> sqlPropertyConnections = new HashSet<>();
+	
+
+	/**
+	 * SQL operation connections
+	 */
+	protected Set<String> sqlOperationConnections = new HashSet<>();
+
+	
+	
+	/**
+	 * Run queries to access properties via 'get' operation
+	 */
+	protected Map<String, DynamicSQLRunner> propertyGetQueries = new HashMap<>();
+
+	
+	/**
+	 * Run SQL update to access properties via 'set' operation
+	 */
+	protected Map<String, DynamicSQLRunner> propertySetQueries = new HashMap<>();
+
+	
+	/**
+	 * Run SQL update to access properties via 'create' operation
+	 */
+	protected Map<String, DynamicSQLRunner> propertyCreateQueries = new HashMap<>();
+
+
+	/**
+	 * Run SQL update to access properties via 'delete' operation
+	 */
+	protected Map<String, DynamicSQLRunner> propertyDeleteQueries = new HashMap<>();
+
+
+	
+	/**
+	 * SQL operations
+	 */
+	protected Map<String, DynamicSQLRunner> operations = new HashMap<>();
+
+	
+	/**
+	 * SQL operations that run as update operations. Not contained operations are query operations.
+	 */
+	protected Set<String> updateOperations = new HashSet<>();
+	
+	/**
+	 * An SQL driver instance to connect to the database
+	 */
+	protected SQLDriver driver;
+
+	
+	public static final String DBUSER = "dbuser";
+	public static final String DBPASS = "dbpass";
+	public static final String DBURL = "dburl";
+	public static final String DRIVER = "driver";
+	public static final String PREFIX = "prefix";
+	public static final String PROPERTIES = "properties";
+	public static final String OPERATIONS = "operations";
+	
+	
+	/**
+	 * Constructor
+	 */
+	public SQLPreconfiguredSubModelProvider(Properties cfgValues) {
+		// Call base constructor
+		super(cfgValues);
+		
+		// Create sub model
+		submodelData = createSubModel(cfgValues);
+
+		// Load predefined elements from sub model
+		
+		try {
+			setModelPropertyValue("", submodelData);
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+
+		
+		// Extract SQL properties
+		sqlUser = cfgValues.getProperty(buildSqlCfgName(DBUSER));
+		sqlPass = cfgValues.getProperty(buildSqlCfgName(DBPASS));
+		sqlURL  = cfgValues.getProperty(buildSqlCfgName(DBURL));
+
+		// Extract SQL driver properties
+		sqlDriver = cfgValues.getProperty(buildSqlCfgName(DRIVER));
+		sqlPrefix = cfgValues.getProperty(buildSqlCfgName(PREFIX));
+		
+		// Create a SQL driver instance
+		driver = new SQLDriver(sqlURL, sqlUser, sqlPass, sqlPrefix, sqlDriver);
+		
+		// Load and parse SQL property and operation connections
+		sqlPropertyConnections.addAll(splitString(cfgValues.getProperty(buildSqlCfgName(PROPERTIES))));
+		sqlOperationConnections.addAll(splitString(cfgValues.getProperty(buildSqlCfgName(OPERATIONS))));
+
+		
+		
+		// Add properties
+		for (String propertyName: sqlPropertyConnections) createSQLProperty(propertyName, cfgValues);
+		
+		/*
+			// Try to parse parameter
+			propertyGetQueries.put(propertyName, createSQLOperation(propertyName+".get", cfgValues));
+			propertySetQueries.put(propertyName, createSQLOperation(propertyName+".set", cfgValues));
+			propertyCreateQueries.put(propertyName, createSQLOperation(propertyName+".create", cfgValues));
+			propertyDeleteQueries.put(propertyName, createSQLOperation(propertyName+".delete", cfgValues));
+			
+			
+			Map<String, Object> mapAccessors = VABLambdaProviderHelper.createMap((Supplier<?>) () -> {
+				return propertyMap_val;
+			}, (Consumer<Map<String, Object>>) (map) -> {
+				propertyMap_val = map;
+			}, (BiConsumer<String, Object>) (key, value) -> {
+				propertyMap_val.put(key, value);
+			}, (Consumer<Object>) (o) -> {
+				propertyMap_val.remove(o);
+			});
+
+		}*/
+		
+		
+		// Add operations
+		//for (String operationName: sqlOperationConnections) createSQLOperation(operationName, cfgValues); 
+		/*{
+			// Create operation
+			operations.put(operationName, createSQLOperation(operationName, cfgValues));
+			// Mark operation as update operation depending on operations/<operationName>_kind property value
+			try {
+				if (cfgValues.getProperty(operationName+"_kind").trim().equalsIgnoreCase("update")) {
+					updateOperations.add(operationName);
+				}
+			} catch (Exception e) {}
+		}*/
+	}
+	
+	
+	
+	/**
+	 * Create an SQL property
+	 */
+	protected void createSQLProperty(String name, Properties cfgValues) {
+		// Create Map with lambdas that hold SQL operations
+		Map<String, Object> value = new HashMap<>();
+		
+		// Get operation
+		{
+			// Get parameter
+			String queryString    = cfgValues.getProperty(name+".get");
+			String resultFilterOp = cfgValues.getProperty(name+".get.result");
+
+			// Trim query string and resultFilterOp (remove '"' at beginning and end)
+			queryString    = queryString.substring(1, queryString.length()-1);
+			try {resultFilterOp = resultFilterOp.substring(1, resultFilterOp.length()-1);} catch (NullPointerException | StringIndexOutOfBoundsException e) {}
+
+			// Create dynamic SQL query
+			value.put(VABLambdaHandler.VALUE_GET_SUFFIX, new DynamicSQLQuery(driver, queryString, resultFilterOp));
+		}
+		
+		// Set operation
+		{
+			// Get parameter
+			String updateString   = cfgValues.getProperty(name+".set");
+
+			// Trim query string and resultFilterOp (remove '"' at beginning and end)
+			updateString    = updateString.substring(1, updateString.length()-1);
+
+			// Create dynamic SQL query
+			value.put(VABLambdaHandler.VALUE_SET_SUFFIX, new DynamicSQLUpdate(driver, updateString));
+		}
+
+		// Delete operation
+		{
+			// Get parameter
+			String updateString   = cfgValues.getProperty(name+".delete");
+
+			// Trim query string and resultFilterOp (remove '"' at beginning and end)
+			updateString    = updateString.substring(1, updateString.length()-1);
+
+			// Create dynamic SQL query
+			value.put(VABLambdaHandler.VALUE_REMOVEKEY_SUFFIX, new DynamicSQLUpdate(driver, updateString));
+			value.put(VABLambdaHandler.VALUE_REMOVEOBJ_SUFFIX, new DynamicSQLUpdate(driver, updateString));
+		}
+		
+		// Create operation
+		{
+			// Get parameter
+			String updateString   = cfgValues.getProperty(name+".create");
+
+			// Trim query string and resultFilterOp (remove '"' at beginning and end)
+			updateString    = updateString.substring(1, updateString.length()-1);
+
+			// Create dynamic SQL query
+			value.put(VABLambdaHandler.VALUE_INSERT_SUFFIX, new DynamicSQLUpdate(driver, updateString));
+		}
+		
+		
+		logger.debug("Putting SQL:"+name);
+		// Add property as map of lambdas
+		submodelData.getProperties().put(name, createSubmodelElement(name, value, cfgValues));
+	}
+
+	
+	/**
+	 * Create a dynamic SQL operation
+	 */
+	protected DynamicSQLRunner createSQLOperation(String propertyName, Properties cfgValues) {/*
+		// Check parameter presence
+		if (!cfgValues.containsKey(propertyName)) return null;
+		
+		// Get parameter count and parameter count
+		int    parameterCount = Integer.parseInt(cfgValues.getProperty(propertyName+".parameter"));
+		String queryString    = cfgValues.getProperty(propertyName);
+		String resultFilterOp = cfgValues.getProperty(propertyName+".result");
+		
+		// Trim query string and resultFilterOp (remove '"' at beginning and end)
+		queryString    = queryString.substring(1, queryString.length()-1);
+		try {resultFilterOp = resultFilterOp.substring(1, resultFilterOp.length()-1);} catch (NullPointerException | StringIndexOutOfBoundsException e) {}
+		
+		// Create dynamic SQL query
+		DynamicSQLRunner sqlQuery = new DynamicSQLRunner(sqlURL, sqlUser, sqlPass, sqlPrefix, sqlDriver, parameterCount, queryString, resultFilterOp);
+
+		// Return created query
+		return sqlQuery;*/
+		
+		return null;
+	}
+	
+	
+	/**
+	 * Split a whitespace delimited string
+	 */
+	@Override
+	protected Collection<String> splitString(String input) {
+		// Return value
+		HashSet<String> result = new HashSet<>();
+		
+		// Split string into segments
+		for (String inputStr: input.split(" ")) result.add(inputStr.trim());
+		
+		// Return result
+		return result;
+	}
+	
+	
+	/**
+	 * Create a key list for an SQL statement
+	 *//*
+	protected String sqlCreateKeys(Collection<String> keys) {
+		// Return value builder
+		StringBuilder result = new StringBuilder();
+		
+		// Process keys
+		// - Flag that handles the first key
+		boolean isFirst = true;
+		// - Process keys
+		for (String key: keys) {if (!isFirst) result.append(","); else isFirst=false; result.append(key);}
+		
+		// Return string
+		return result.toString();
+	}*/
+	
+	
+	/**
+	 * Extract a list of values from a map
+	 *//*
+	protected String sqlCreateValues(Collection<Object> values) {
+		// Return value builder
+		StringBuilder result = new StringBuilder();
+		
+		// Process keys
+		// - Flag that handles the first key
+		boolean isFirst = true;
+		// - Process keys
+		for (Object key: values) {if (!isFirst) result.append(","); else isFirst=false; result.append("'"+key+"'");}
+		
+		// Return string
+		return result.toString();
+	}*/
+
+
+	
+	/**
+	 * Create (insert) a value into the SQL table
+	 *//*
+	@Override @SuppressWarnings("unchecked")
+	public void createValue(String propertyName, Object arg1) throws Exception {
+		// Set query
+		DynamicSQLRunner query = propertyCreateQueries.get(propertyName);
+		
+		// Null pointer check
+		if (query == null) return;
+		
+		// Create parameter array
+		Object[] parameter = new Object[2];
+		parameter[0] = sqlCreateKeys(((Map<String, Object>) arg1).keySet());
+		parameter[1] = sqlCreateValues(((Map<String, Object>) arg1).values());
+		
+		// Execute query and return result
+		query.runUpdate(parameter);
+	}*/
+
+
+	
+	/**
+	 * Delete a value from the SQL table
+	 *//*
+	@Override
+	public void deleteValue(String arg0) throws Exception {
+		// This is not implemented
+	}*/
+
+
+	
+	/**
+	 * Delete a value from the SQL table
+	 *//*
+	@Override @SuppressWarnings("unchecked")
+	public void deleteValue(String propertyName, Object arg1) throws Exception {
+		// Set query
+		DynamicSQLRunner query = propertyDeleteQueries.get(propertyName);
+		
+		// Null pointer check
+		if (query == null) return;
+
+		// Cast argument to collection
+		Collection<Object> parameterList = (Collection<Object>) arg1;
+		
+		// Create parameter array
+		Object[] parameter = new Object[parameterList.size()];
+		// - Copy parameter
+		int counter = 0; for (Object par: parameterList) parameter[counter++] = par;
+		
+		// Execute query and return result
+		query.runUpdate(parameter);
+	}*/
+
+	
+/*
+	@Override
+	public Map<String, IElementReference> getContainedElements(String arg0) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+
+	@Override
+	public String getElementScope(String arg0) {
+		logger.debug("GetScope:"+arg0);
+		// TODO Auto-generated method stub
+		return null;
+	}
+*/
+
+	
+	/**
+	 * Query the SQL database
+	 *//*
+	@Override
+	public Object getModelPropertyValue(String propertyName) {
+		// Get query
+		DynamicSQLRunner query = propertyGetQueries.get(propertyName);
+		
+		// Null pointer check
+		if (query == null) return null;
+		
+		// Execute query and return result
+		return query.runQuery();
+	}*/
+
+
+	
+	/**
+	 * Invoke operation with given parameter list
+	 *//*
+	@Override
+	public Object invokeOperation(String propertyName, Object[] parameter) throws Exception {
+		// Set query
+		DynamicSQLRunner query = operations.get(propertyName);
+		
+		// Null pointer check
+		if (query == null) return null;
+		
+		// Execute query and return result
+		if (updateOperations.contains(propertyName)) {
+			query.runUpdate(parameter); 
+			return null; 
+		} else {
+			return query.runQuery(parameter);
+		}
+	}*/
+
+
+	
+	/**
+	 * Invoke set operation with given parameter
+	 *//*
+	@Override @SuppressWarnings("unchecked")
+	public void setModelPropertyValue(String propertyName, Object arg1) throws Exception {
+		// Set query
+		DynamicSQLRunner query = propertySetQueries.get(propertyName);
+		
+		// Null pointer check
+		if (query == null) return;
+
+		logger.debug("LENC:"+arg1);
+
+		// Create parameter array
+		Object[] parameter = null;
+		// - Process collections
+		if (arg1 instanceof Collection) {
+			// Cast to collection
+			Collection<Object> parameterList = (Collection<Object>) arg1;
+			
+			// Create parameter array and copy parameter
+			parameter = new Object[parameterList.size()];
+			int counter = 0; for (Object par: parameterList) parameter[counter++] = par;
+		} else {
+			// Create parameter array and copy parameter
+			parameter = new Object[1];
+			parameter[0] = arg1;			
+		}
+		
+		
+		// Execute query and return result
+		query.runUpdate(parameter);
+	}*/
+
+
+	
+	/**
+	 * Invoke set operation with given parameter list
+	 *//*
+	@Override
+	public void setModelPropertyValue(String propertyName, Object... parameter) throws Exception {
+		// Set query
+		DynamicSQLRunner query = propertySetQueries.get(propertyName);
+		
+		// Null pointer check
+		if (query == null) return;
+		
+		logger.debug("LEN:"+parameter.length);
+		logger.debug("LEN-0:"+parameter[0]);
+
+		// Execute query and return result
+		query.runUpdate(parameter);
+	}*/
+	
+	public static String buildSqlCfgName(String valueName) {
+		return BaseConfiguredProvider.buildCfgName("basyx.sql", valueName);
+	}
+}
diff --git a/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/sqlprovider/SQLProviderTestOLD.java b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/sqlprovider/SQLProviderTestOLD.java
new file mode 100644
index 0000000..c2a5344
--- /dev/null
+++ b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/sqlprovider/SQLProviderTestOLD.java
@@ -0,0 +1,186 @@
+package org.eclipse.basyx.sandbox.components.sqlprovider;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Collection;
+import java.util.LinkedList;
+
+import org.eclipse.basyx.tools.sql.driver.ISQLDriver;
+import org.eclipse.basyx.tools.sql.driver.SQLDriver;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SQLProviderTestOLD {
+	
+	/**
+	 * Initiates a logger using the current class
+	 */
+	private static final Logger logger = LoggerFactory.getLogger(SQLProviderTestOLD.class);
+
+	
+	/**
+	 * Define a parameter tuple (name/type)
+	 * 
+	 * @author kuhn
+	 *
+	 */
+	static class Parameter {
+		String name;
+		String type;
+		
+		
+		/**
+		 * Constructor 
+		 * 
+		 * @param name  Parameter name
+		 * @param type  Parameter type
+		 */
+		Parameter(String name, String type) {
+			this.name = name;
+			this.type = type;
+		}
+		
+		
+		/**
+		 * Return parameter name
+		 * 
+		 * @return parameter name
+		 */
+		public String getName() {
+			return name;
+		}
+		
+		
+		/**
+		 * Return parameter type
+		 * 
+		 * @return parameter type
+		 */
+		public String getType() {
+			return type;
+		}
+	}
+	
+	
+	
+	
+	/**
+	 * Get operation name of operation definition 
+	 * 
+	 * @param opDef The operation definition string
+	 * @return Operation name
+	 */
+	public static String getOperation(String opDef) {
+		// Get operation name
+		return opDef.substring(0, opDef.indexOf("("));
+	}
+	
+	
+	
+	/**
+	 * Get parameter list of an operation definition
+	 * 
+	 * A parameter list contains of a name and of a type for each parameter+
+	 * 
+	 * @param opDef The operation definition string
+	 * @return Collection of Parameter definitions
+	 */
+	public static Collection<Parameter> getParameter(String opDef) {
+		// Return type
+		LinkedList<Parameter> result = new LinkedList<>();
+		
+		// Extract parameter sequence
+		String   callParameterStr  = opDef.substring(opDef.indexOf("(")+1, opDef.length()-1);
+		String[] callParameterList = callParameterStr.split(",");
+		
+		// Iterate all parameter. If no parameter is given, the loop will execute once with an empty String (length = 0)
+		for (String parameterDef: callParameterList) {
+			// Only process strings with a length > 0
+			if (parameterDef.length() == 0) continue;
+			
+			// Add parameter
+			result.add(new Parameter(parameterDef.substring(0, parameterDef.indexOf(":")).trim(), parameterDef.substring(parameterDef.indexOf(":")+1).trim().toLowerCase()));			
+		}
+		
+		// Return result
+		return result;
+	}
+	
+	
+
+	/**
+	 * Create a SQL string from an input SQL string with place holders in format $x with x being an integer number.
+	 * 
+	 * @param baseString SQL string with place holders
+	 * @param parameter Parameter values that place holders are substituted for
+	 * 
+	 * @return SQL string with parameter instead of place holders
+	 */
+	public static String getSQLString(String baseString, Collection<String> parameter) {
+		// Resulting SQL String
+		String result = baseString;
+		
+		// Replace place holders with parameter
+		// - Counter variable
+		int counter = 1;
+		// - Replace all place holders
+		for (String par: parameter) {
+			result = result.replace("$"+counter, par);
+			counter++;
+		}
+		
+		// Return SQL string with resolved parameter
+		return result;
+	}
+
+	
+	
+	public static void main(String[] args) throws SQLException {
+		logger.debug("Test");
+		
+		ISQLDriver sqlDriver = new SQLDriver("localhost:5432/basyx-sample-vibrations", "postgres", "admin", "jdbc:postgresql://", "org.postgresql.Driver");
+
+		
+		
+		Collection<String> sqlQuery1Params = new LinkedList<>();
+		sqlQuery1Params.add(Integer.valueOf(1).toString());
+		String     sqlQuery1String = getSQLString("SELECT * FROM vibrations.sensors WHERE vibrations.sensors.sensorid='$1'", sqlQuery1Params);
+		
+		ResultSet result1 = sqlDriver.sqlQuery(sqlQuery1String);
+		
+		logger.debug(""+result1);
+		logger.debug(""+result1.next());
+		logger.debug("ID   : "+result1.getString("sensorid"));
+		logger.debug("NAME : "+result1.getString("sensorname"));
+		logger.debug(""+result1.next());
+
+		
+		
+		Collection<String> sqlQuery2Params = new LinkedList<>();
+		sqlQuery2Params.add("vibrations.sensors.sensorid");
+		sqlQuery2Params.add(Integer.valueOf(1).toString());
+		String     sqlQuery2String = getSQLString("SELECT * FROM vibrations.sensors WHERE $1='$2'", sqlQuery2Params);
+		
+		ResultSet result2 = sqlDriver.sqlQuery(sqlQuery2String);
+		
+		logger.debug(""+result2);
+		logger.debug(""+result2.next());
+		logger.debug("ID   : "+result2.getString("sensorid"));
+		logger.debug("NAME : "+result2.getString("sensorname"));
+		logger.debug(""+result2.next());
+
+
+		
+		String call1 = "MapString()";
+		
+		logger.debug("- "+getOperation(call1));
+		logger.debug("- "+getParameter(call1));
+
+		
+		String call2 = "MapArray(sensorid:int, sensorname:String)";
+		
+		logger.debug("- "+getOperation(call2));
+		logger.debug("- "+getParameter(call2));
+		
+	}
+}
diff --git a/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/sqlprovider/SQLSubModelProvider.java b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/sqlprovider/SQLSubModelProvider.java
new file mode 100644
index 0000000..38914d3
--- /dev/null
+++ b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/sqlprovider/SQLSubModelProvider.java
@@ -0,0 +1,512 @@
+package org.eclipse.basyx.sandbox.components.sqlprovider;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+
+import org.eclipse.basyx.components.provider.BaseConfiguredProvider;
+import org.eclipse.basyx.tools.sql.driver.SQLDriver;
+import org.eclipse.basyx.tools.sql.query.DynamicSQLQuery;
+import org.eclipse.basyx.tools.sql.query.DynamicSQLRunner;
+import org.eclipse.basyx.tools.sql.query.DynamicSQLUpdate;
+import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaHandler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+
+
+/**
+ * Asset administration shell sub model provider that connects to SQL database
+ * 
+ * @author kuhn
+ * 
+ */
+public class SQLSubModelProvider extends BaseConfiguredProvider {
+
+	/**
+	 * Initiates a logger using the current class
+	 */
+	private static final Logger logger = LoggerFactory.getLogger(SQLSubModelProvider.class);
+	
+	/**
+	 * SQL database user name
+	 */
+	protected String sqlUser = null;
+
+	/**
+	 * SQL database password
+	 */
+	protected String sqlPass = null;
+	
+	/**
+	 * SQL database path
+	 */
+	protected String sqlURL  = null;
+
+	
+	
+	/**
+	 * SQL database driver
+	 */
+	protected String sqlDriver = null;
+	
+	/**
+	 * SQL database query prefix
+	 */
+	protected String sqlPrefix = null;
+	
+	/**
+	 * An SQL driver instance to connect to the database
+	 */
+	protected SQLDriver driver;
+	
+	
+	/**
+	 * SQL property connections
+	 */
+	protected Set<String> sqlPropertyConnections = new HashSet<>();
+	
+
+	/**
+	 * SQL operation connections
+	 */
+	protected Set<String> sqlOperationConnections = new HashSet<>();
+
+	
+	
+	/**
+	 * Run queries to access properties via 'get' operation
+	 */
+	protected Map<String, DynamicSQLRunner> propertyGetQueries = new HashMap<>();
+
+	
+	/**
+	 * Run SQL update to access properties via 'set' operation
+	 */
+	protected Map<String, DynamicSQLRunner> propertySetQueries = new HashMap<>();
+
+	
+	/**
+	 * Run SQL update to access properties via 'create' operation
+	 */
+	protected Map<String, DynamicSQLRunner> propertyCreateQueries = new HashMap<>();
+
+
+	/**
+	 * Run SQL update to access properties via 'delete' operation
+	 */
+	protected Map<String, DynamicSQLRunner> propertyDeleteQueries = new HashMap<>();
+
+
+	
+	/**
+	 * SQL operations
+	 */
+	protected Map<String, DynamicSQLRunner> operations = new HashMap<>();
+
+	
+	/**
+	 * SQL operations that run as update operations. Not contained operations are query operations.
+	 */
+	protected Set<String> updateOperations = new HashSet<>();
+
+	
+	
+	
+	/**
+	 * Constructor
+	 */
+	public SQLSubModelProvider(Properties cfgValues) {
+		// Call base constructor
+		super(cfgValues);
+		
+		// Create sub model
+		submodelData = createSubModel(cfgValues);
+
+		// Load predefined elements from sub model
+		try {
+			setModelPropertyValue("", submodelData);
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+
+		
+		// Extract SQL properties
+		sqlUser = cfgValues.getProperty(
+				SQLPreconfiguredSubModelProvider.buildSqlCfgName(SQLPreconfiguredSubModelProvider.DBUSER));
+		sqlPass = cfgValues.getProperty(
+				SQLPreconfiguredSubModelProvider.buildSqlCfgName(SQLPreconfiguredSubModelProvider.DBPASS));
+		sqlURL  = cfgValues.getProperty(
+				SQLPreconfiguredSubModelProvider.buildSqlCfgName(SQLPreconfiguredSubModelProvider.DBURL));
+
+		// Extract SQL driver properties
+		sqlDriver = cfgValues.getProperty(
+				SQLPreconfiguredSubModelProvider.buildSqlCfgName(SQLPreconfiguredSubModelProvider.DRIVER));
+		sqlPrefix = cfgValues.getProperty(
+				SQLPreconfiguredSubModelProvider.buildSqlCfgName(SQLPreconfiguredSubModelProvider.PREFIX));
+		
+		// Create a SQL driver instance
+		driver = new SQLDriver(sqlURL, sqlUser, sqlPass, sqlPrefix, sqlDriver);
+		
+		// Load and parse SQL property and operation connections
+		sqlPropertyConnections.addAll(splitString(cfgValues.getProperty(
+				SQLPreconfiguredSubModelProvider.buildSqlCfgName(SQLPreconfiguredSubModelProvider.PROPERTIES))));
+		sqlOperationConnections.addAll(splitString(cfgValues.getProperty(
+				SQLPreconfiguredSubModelProvider.buildSqlCfgName(SQLPreconfiguredSubModelProvider.OPERATIONS))));
+
+		
+		
+		// Add properties
+		for (String propertyName: sqlPropertyConnections) createSQLProperty(propertyName, cfgValues);
+		
+		/*
+			// Try to parse parameter
+			propertyGetQueries.put(propertyName, createSQLOperation(propertyName+".get", cfgValues));
+			propertySetQueries.put(propertyName, createSQLOperation(propertyName+".set", cfgValues));
+			propertyCreateQueries.put(propertyName, createSQLOperation(propertyName+".create", cfgValues));
+			propertyDeleteQueries.put(propertyName, createSQLOperation(propertyName+".delete", cfgValues));
+			
+			
+			Map<String, Object> mapAccessors = VABLambdaProviderHelper.createMap((Supplier<?>) () -> {
+				return propertyMap_val;
+			}, (Consumer<Map<String, Object>>) (map) -> {
+				propertyMap_val = map;
+			}, (BiConsumer<String, Object>) (key, value) -> {
+				propertyMap_val.put(key, value);
+			}, (Consumer<Object>) (o) -> {
+				propertyMap_val.remove(o);
+			});
+
+		}*/
+		
+		
+		// Add operations
+		//for (String operationName: sqlOperationConnections) createSQLOperation(operationName, cfgValues); 
+		/*{
+			// Create operation
+			operations.put(operationName, createSQLOperation(operationName, cfgValues));
+			// Mark operation as update operation depending on operations/<operationName>_kind property value
+			try {
+				if (cfgValues.getProperty(operationName+"_kind").trim().equalsIgnoreCase("update")) {
+					updateOperations.add(operationName);
+				}
+			} catch (Exception e) {}
+		}*/
+	}
+	
+	
+	
+	/**
+	 * Create an SQL property
+	 */
+	protected void createSQLProperty(String name, Properties cfgValues) {
+		// Create Map with lambdas that hold SQL operations
+		Map<String, Object> value = new HashMap<>();
+		
+		// Get operation
+		{
+			// Get parameter
+			String queryString    = cfgValues.getProperty(name+".get");
+			String resultFilterOp = cfgValues.getProperty(name+".get.result");
+
+			// Trim query string and resultFilterOp (remove '"' at beginning and end)
+			queryString    = queryString.substring(1, queryString.length()-1);
+			try {resultFilterOp = resultFilterOp.substring(1, resultFilterOp.length()-1);} catch (NullPointerException | StringIndexOutOfBoundsException e) {}
+
+			// Create dynamic SQL query
+			value.put(VABLambdaHandler.VALUE_GET_SUFFIX, new DynamicSQLQuery(driver, queryString, resultFilterOp));
+		}
+		
+		// Set operation
+		{
+			// Get parameter
+			String updateString   = cfgValues.getProperty(name+".set");
+
+			// Trim query string and resultFilterOp (remove '"' at beginning and end)
+			updateString    = updateString.substring(1, updateString.length()-1);
+
+			// Create dynamic SQL query
+			value.put(VABLambdaHandler.VALUE_SET_SUFFIX, new DynamicSQLUpdate(driver, updateString));
+		}
+
+		// Delete operation
+		{
+			// Get parameter
+			String updateString   = cfgValues.getProperty(name+".delete");
+
+			// Trim query string and resultFilterOp (remove '"' at beginning and end)
+			updateString    = updateString.substring(1, updateString.length()-1);
+
+			// Create dynamic SQL query
+			value.put(VABLambdaHandler.VALUE_REMOVEKEY_SUFFIX, new DynamicSQLUpdate(driver, updateString));
+			value.put(VABLambdaHandler.VALUE_REMOVEOBJ_SUFFIX, new DynamicSQLUpdate(driver, updateString));
+		}
+		
+		// Create operation
+		{
+			// Get parameter
+			String updateString   = cfgValues.getProperty(name+".create");
+
+			// Trim query string and resultFilterOp (remove '"' at beginning and end)
+			updateString    = updateString.substring(1, updateString.length()-1);
+
+			// Create dynamic SQL query
+			value.put(VABLambdaHandler.VALUE_INSERT_SUFFIX, new DynamicSQLUpdate(driver, updateString));
+		}
+		
+		
+		logger.debug("Putting SQL:"+name);
+		// Add property as map of lambdas
+		submodelData.getProperties().put(name, createSubmodelElement(name, value, cfgValues));
+	}
+
+	
+	/**
+	 * Create a dynamic SQL operation
+	 */
+	protected DynamicSQLRunner createSQLOperation(String propertyName, Properties cfgValues) {/*
+		// Check parameter presence
+		if (!cfgValues.containsKey(propertyName)) return null;
+		
+		// Get parameter count and parameter count
+		int    parameterCount = Integer.parseInt(cfgValues.getProperty(propertyName+".parameter"));
+		String queryString    = cfgValues.getProperty(propertyName);
+		String resultFilterOp = cfgValues.getProperty(propertyName+".result");
+		
+		// Trim query string and resultFilterOp (remove '"' at beginning and end)
+		queryString    = queryString.substring(1, queryString.length()-1);
+		try {resultFilterOp = resultFilterOp.substring(1, resultFilterOp.length()-1);} catch (NullPointerException | StringIndexOutOfBoundsException e) {}
+		
+		// Create dynamic SQL query
+		DynamicSQLRunner sqlQuery = new DynamicSQLRunner(sqlURL, sqlUser, sqlPass, sqlPrefix, sqlDriver, parameterCount, queryString, resultFilterOp);
+
+		// Return created query
+		return sqlQuery;*/
+		
+		return null;
+	}
+	
+	
+	/**
+	 * Split a whitespace delimited string
+	 */
+	@Override
+	protected Collection<String> splitString(String input) {
+		// Return value
+		HashSet<String> result = new HashSet<>();
+		
+		// Split string into segments
+		for (String inputStr: input.split(" ")) result.add(inputStr.trim());
+		
+		// Return result
+		return result;
+	}
+	
+	
+	/**
+	 * Create a key list for an SQL statement
+	 *//*
+	protected String sqlCreateKeys(Collection<String> keys) {
+		// Return value builder
+		StringBuilder result = new StringBuilder();
+		
+		// Process keys
+		// - Flag that handles the first key
+		boolean isFirst = true;
+		// - Process keys
+		for (String key: keys) {if (!isFirst) result.append(","); else isFirst=false; result.append(key);}
+		
+		// Return string
+		return result.toString();
+	}*/
+	
+	
+	/**
+	 * Extract a list of values from a map
+	 *//*
+	protected String sqlCreateValues(Collection<Object> values) {
+		// Return value builder
+		StringBuilder result = new StringBuilder();
+		
+		// Process keys
+		// - Flag that handles the first key
+		boolean isFirst = true;
+		// - Process keys
+		for (Object key: values) {if (!isFirst) result.append(","); else isFirst=false; result.append("'"+key+"'");}
+		
+		// Return string
+		return result.toString();
+	}*/
+
+
+	
+	/**
+	 * Create (insert) a value into the SQL table
+	 *//*
+	@Override @SuppressWarnings("unchecked")
+	public void createValue(String propertyName, Object arg1) throws Exception {
+		// Set query
+		DynamicSQLRunner query = propertyCreateQueries.get(propertyName);
+		
+		// Null pointer check
+		if (query == null) return;
+		
+		// Create parameter array
+		Object[] parameter = new Object[2];
+		parameter[0] = sqlCreateKeys(((Map<String, Object>) arg1).keySet());
+		parameter[1] = sqlCreateValues(((Map<String, Object>) arg1).values());
+		
+		// Execute query and return result
+		query.runUpdate(parameter);
+	}*/
+
+
+	
+	/**
+	 * Delete a value from the SQL table
+	 *//*
+	@Override
+	public void deleteValue(String arg0) throws Exception {
+		// This is not implemented
+	}*/
+
+
+	
+	/**
+	 * Delete a value from the SQL table
+	 *//*
+	@Override @SuppressWarnings("unchecked")
+	public void deleteValue(String propertyName, Object arg1) throws Exception {
+		// Set query
+		DynamicSQLRunner query = propertyDeleteQueries.get(propertyName);
+		
+		// Null pointer check
+		if (query == null) return;
+
+		// Cast argument to collection
+		Collection<Object> parameterList = (Collection<Object>) arg1;
+		
+		// Create parameter array
+		Object[] parameter = new Object[parameterList.size()];
+		// - Copy parameter
+		int counter = 0; for (Object par: parameterList) parameter[counter++] = par;
+		
+		// Execute query and return result
+		query.runUpdate(parameter);
+	}*/
+
+	
+/*
+	@Override
+	public Map<String, IElementReference> getContainedElements(String arg0) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+
+	@Override
+	public String getElementScope(String arg0) {
+		logger.debug("GetScope:"+arg0);
+		// TODO Auto-generated method stub
+		return null;
+	}
+*/
+
+	
+	/**
+	 * Query the SQL database
+	 *//*
+	@Override
+	public Object getModelPropertyValue(String propertyName) {
+		// Get query
+		DynamicSQLRunner query = propertyGetQueries.get(propertyName);
+		
+		// Null pointer check
+		if (query == null) return null;
+		
+		// Execute query and return result
+		return query.runQuery();
+	}*/
+
+
+	
+	/**
+	 * Invoke operation with given parameter list
+	 *//*
+	@Override
+	public Object invokeOperation(String propertyName, Object[] parameter) throws Exception {
+		// Set query
+		DynamicSQLRunner query = operations.get(propertyName);
+		
+		// Null pointer check
+		if (query == null) return null;
+		
+		// Execute query and return result
+		if (updateOperations.contains(propertyName)) {
+			query.runUpdate(parameter); 
+			return null; 
+		} else {
+			return query.runQuery(parameter);
+		}
+	}*/
+
+
+	
+	/**
+	 * Invoke set operation with given parameter
+	 *//*
+	@Override @SuppressWarnings("unchecked")
+	public void setModelPropertyValue(String propertyName, Object arg1) throws Exception {
+		// Set query
+		DynamicSQLRunner query = propertySetQueries.get(propertyName);
+		
+		// Null pointer check
+		if (query == null) return;
+
+		logger.debug("LENC:"+arg1);
+
+		// Create parameter array
+		Object[] parameter = null;
+		// - Process collections
+		if (arg1 instanceof Collection) {
+			// Cast to collection
+			Collection<Object> parameterList = (Collection<Object>) arg1;
+			
+			// Create parameter array and copy parameter
+			parameter = new Object[parameterList.size()];
+			int counter = 0; for (Object par: parameterList) parameter[counter++] = par;
+		} else {
+			// Create parameter array and copy parameter
+			parameter = new Object[1];
+			parameter[0] = arg1;			
+		}
+		
+		
+		// Execute query and return result
+		query.runUpdate(parameter);
+	}*/
+
+
+	
+	/**
+	 * Invoke set operation with given parameter list
+	 *//*
+	@Override
+	public void setModelPropertyValue(String propertyName, Object... parameter) throws Exception {
+		// Set query
+		DynamicSQLRunner query = propertySetQueries.get(propertyName);
+		
+		// Null pointer check
+		if (query == null) return;
+		
+		logger.debug("LEN:"+parameter.length);
+		logger.debug("LEN-0:"+parameter[0]);
+
+		// Execute query and return result
+		query.runUpdate(parameter);
+	}*/
+}
diff --git a/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/sqlprovider/servlet/SQLSubModelProviderServlet.java b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/sqlprovider/servlet/SQLSubModelProviderServlet.java
new file mode 100644
index 0000000..7ee2fab
--- /dev/null
+++ b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/sqlprovider/servlet/SQLSubModelProviderServlet.java
@@ -0,0 +1,79 @@
+package org.eclipse.basyx.sandbox.components.sqlprovider.servlet;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+
+import javax.servlet.ServletException;
+
+import org.eclipse.basyx.aas.restapi.VABMultiSubmodelProvider;
+import org.eclipse.basyx.components.provider.BaseConfiguredProvider;
+import org.eclipse.basyx.sandbox.components.sqlprovider.SQLPreconfiguredSubModelProvider;
+import org.eclipse.basyx.vab.protocol.http.server.VABHTTPInterface;
+
+/**
+ * Servlet interface for SQL sub model provider
+ * 
+ * @author kuhn
+ *
+ */
+public class SQLSubModelProviderServlet extends VABHTTPInterface<VABMultiSubmodelProvider> {
+
+	/**
+	 * Version information to identify the version of serialized instances
+	 */
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * Sub model ID
+	 */
+	protected String submodelID = null;
+
+	/**
+	 * Configuration properties
+	 */
+	protected Properties cfgProperties = null;
+
+	/**
+	 * Constructor
+	 */
+	public SQLSubModelProviderServlet() {
+		// Invoke base constructor
+		super(new VABMultiSubmodelProvider());
+	}
+
+	/**
+	 * Initialize servlet
+	 * 
+	 * @throws ServletException
+	 */
+	public void init() throws ServletException {
+		// Call base implementation
+		super.init();
+
+		// Read configuration values
+		String configFilePath = (String) getInitParameter("config");
+
+		// Read property file
+		try {
+			// Open property file
+			InputStream input = getServletContext().getResourceAsStream(configFilePath);
+
+			// Instantiate property structure
+			cfgProperties = new Properties();
+			cfgProperties.load(input);
+
+			// Extract sub model provider properties
+			this.submodelID = cfgProperties.getProperty(BaseConfiguredProvider.buildBasyxCfgName(BaseConfiguredProvider.SUBMODELID));
+
+		} catch (IOException e) {
+			// Output exception
+			e.printStackTrace();
+		}
+
+		// Instantiate and add sub model provider
+		SQLPreconfiguredSubModelProvider sqlSMProvider = new SQLPreconfiguredSubModelProvider(cfgProperties);
+		// - Add sub model provider
+		this.getModelProvider().addSubmodel(submodelID, sqlSMProvider);
+	}
+}
diff --git a/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/xmlxqueryprovider/OperationNotImplementedException.java b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/xmlxqueryprovider/OperationNotImplementedException.java
index 8cae16a..1ee8d3b 100644
--- a/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/xmlxqueryprovider/OperationNotImplementedException.java
+++ b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/xmlxqueryprovider/OperationNotImplementedException.java
@@ -1,6 +1,6 @@
 package org.eclipse.basyx.sandbox.components.xmlxqueryprovider;
 
-
+import org.eclipse.basyx.vab.exception.provider.ProviderException;
 
 /**
  * Exception that indicates that a requested operation is not implemented
@@ -8,9 +8,13 @@
  * @author kuhn
  *
  */
-public class OperationNotImplementedException extends RuntimeException {
+public class OperationNotImplementedException extends ProviderException {
 
 	
+	public OperationNotImplementedException() {
+		super("Operation not implemented");
+	}
+
 	/**
 	 * Version of serialized instances
 	 */
diff --git a/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/xmlxqueryprovider/XMLXQuerySubModelProvider.java b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/xmlxqueryprovider/XMLXQuerySubModelProvider.java
index 37be45b..1b6e539 100644
--- a/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/xmlxqueryprovider/XMLXQuerySubModelProvider.java
+++ b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/xmlxqueryprovider/XMLXQuerySubModelProvider.java
@@ -261,7 +261,7 @@
 	 * Create (insert) a value into the SQL table
 	 */
 	@Override
-	public void createValue(String propertyName, Object arg1) throws Exception {
+	public void createValue(String propertyName, Object arg1) {
 		// Indicate exception
 		throw new OperationNotImplementedException();
 	}
@@ -272,7 +272,7 @@
 	 * Delete a value from the SQL table
 	 */
 	@Override
-	public void deleteValue(String arg0) throws Exception {
+	public void deleteValue(String arg0) {
 		// Indicate exception
 		throw new OperationNotImplementedException();
 	}
@@ -283,7 +283,7 @@
 	 * Delete a value from the SQL table
 	 */
 	@Override
-	public void deleteValue(String propertyName, Object arg1) throws Exception {
+	public void deleteValue(String propertyName, Object arg1) {
 		// Indicate exception
 		throw new OperationNotImplementedException();
 	}
@@ -313,7 +313,7 @@
 	 * Invoke operation with given parameter list
 	 */
 	@Override
-	public Object invokeOperation(String propertyName, Object... parameter) throws Exception {
+	public Object invokeOperation(String propertyName, Object... parameter) {
 		// Indicate exception
 		throw new OperationNotImplementedException();
 	}
@@ -324,7 +324,7 @@
 	 * Invoke set operation with given parameter
 	 */
 	@Override
-	public void setModelPropertyValue(String propertyName, Object arg1) throws Exception {
+	public void setModelPropertyValue(String propertyName, Object arg1) {
 		// Indicate exception
 		throw new OperationNotImplementedException();
 	}
@@ -334,7 +334,7 @@
 	/**
 	 * Invoke set operation with given parameter list
 	 */
-	public void setModelPropertyValue(String propertyName, Object... parameter) throws Exception {
+	public void setModelPropertyValue(String propertyName, Object... parameter) {
 		// Indicate exception
 		throw new OperationNotImplementedException();
 	}
diff --git a/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/models/manufacturing/process/product/ProductQualitySubmodel.java b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/models/manufacturing/process/product/ProductQualitySubmodel.java
index 3631953..ae787c6 100644
--- a/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/models/manufacturing/process/product/ProductQualitySubmodel.java
+++ b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/models/manufacturing/process/product/ProductQualitySubmodel.java
@@ -36,7 +36,7 @@
 		this.setIdShort(id);
 		
 		// Add quality data property
-		getDataElements().put("qualityData", new Property(qualityData));
+		getProperties().put("qualityData", new Property(qualityData));
 		
 		// Add access operations for quality data
 		// - Add a quality data entry
diff --git a/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/code/BaSyxCreateProvideUseExampleAASSubmodel.java b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/code/BaSyxCreateProvideUseExampleAASSubmodel.java
new file mode 100644
index 0000000..9ca9e9d
--- /dev/null
+++ b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/code/BaSyxCreateProvideUseExampleAASSubmodel.java
@@ -0,0 +1,66 @@
+package org.eclipse.basyx.examples.snippets.undoc.aas.code;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Map;
+
+import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.restapi.SubModelProvider;
+import org.eclipse.basyx.submodel.restapi.MultiSubmodelElementProvider;
+import org.eclipse.basyx.vab.coder.json.connector.JSONConnector;
+import org.eclipse.basyx.vab.protocol.basyx.connector.BaSyxConnector;
+import org.eclipse.basyx.vab.protocol.basyx.server.BaSyxTCPServer;
+import org.junit.Test;
+
+/**
+ * Illustrate manual creation and providing of AAS sub model
+ * 
+ * @author kuhn
+ *
+ */
+public class BaSyxCreateProvideUseExampleAASSubmodel {
+
+	
+	/**
+	 * Create, export, and access an example AAS sub model
+	 */
+	@SuppressWarnings("unchecked")
+	@Test
+	public void createExportAndAccessSubModel() throws Exception {
+				
+		// Create sub model and add properties
+		SubModel statusSM = new SubModel();
+		//   - Property status: indicate device status
+		Property statusProp = new Property("offline");
+		statusProp.setIdShort("status");
+		statusSM.addSubModelElement(statusProp);
+		//   - Property statistics: export invocation statistics for every service
+		//     - invocations: indicate total service invocations. Properties are not persisted in this example,
+		//                    therefore we start counting always at 0.
+		Property invocationsProp = new Property(0);
+		invocationsProp.setIdShort("invocations");
+		statusSM.addSubModelElement(invocationsProp);
+
+		
+		// Provide sub model via BaSyx server
+		BaSyxTCPServer<SubModelProvider> server = new BaSyxTCPServer<>(new SubModelProvider(statusSM), 9998);
+		// - Start local BaSyx/TCP server
+		server.start();
+
+		
+		// Access BaSyx TCP server
+		// - Create BaSyx connector to connect with the sub model
+		BaSyxConnector basyxConnector = new BaSyxConnector("localhost", 9998);
+		// - Create connection to device manager
+		JSONConnector toDeviceManager = new JSONConnector(basyxConnector);	
+		// - Access sub model property, check value
+		Map<String, Object> property = (Map<String, Object>) toDeviceManager
+				.getModelPropertyValue(MultiSubmodelElementProvider.ELEMENTS + "/status");
+		assertEquals("offline", property.get("value"));
+		
+		
+		// Stop local BaSyx/TCP server
+		server.stop();
+	}
+}
diff --git a/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/connection/servlet/AASServletConnection.java b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/connection/servlet/AASServletConnection.java
new file mode 100644
index 0000000..10a4bb7
--- /dev/null
+++ b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/connection/servlet/AASServletConnection.java
@@ -0,0 +1,142 @@
+package org.eclipse.basyx.examples.snippets.undoc.aas.connection.servlet;
+
+import static org.junit.Assert.assertTrue;
+
+import java.util.Map;
+
+import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
+import org.eclipse.basyx.components.servlet.submodel.SubmodelServlet;
+import org.eclipse.basyx.examples.contexts.BaSyxExamplesContext_Empty;
+import org.eclipse.basyx.examples.deployment.BaSyxDeployment;
+import org.eclipse.basyx.examples.support.directory.ExampleAASRegistry;
+import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
+import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElementCollection;
+import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.restapi.MultiSubmodelElementProvider;
+import org.eclipse.basyx.vab.manager.VABConnectionManager;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
+import org.junit.ClassRule;
+import org.junit.Test;
+
+/**
+ * Export sub model through a servlet and connect to that servlet
+ * 
+ * @author kuhn
+ *
+ */
+public class AASServletConnection {
+
+	
+	/**
+	 * Example sub model. This example sub model is created with the BaSyx SDK factory and defines the AAS meta model properties
+	 */
+	static class SampleSubModelFactory extends SubModel {
+		/**
+		 * Constructor - create sub model property
+		 */
+		@SuppressWarnings("unchecked")
+		public SampleSubModelFactory() {
+			// Set sub model ID
+			setIdShort("sm-001");
+
+			// Add example properties
+			// - Add simple property
+			Property prop1 = new Property(234);
+			prop1.setIdShort("prop1");
+			addSubModelElement(prop1);
+
+			Property prop11 = new Property(123);
+			prop11.setIdShort("prop11");
+			// - Add container property that holds other properties
+			SubmodelElementCollection container = new SubmodelElementCollection();
+			container.setIdShort("prop2");
+			container.addSubModelElement(prop11);
+			// - Add container to property map
+			addSubModelElement(container);
+
+			// Add another property manually to sub model container "properties"
+			Property prop3 = new Property(17);
+			prop3.setIdShort("prop3");
+			{
+				((Map<String, Object>) this.get("submodelElements")).put("prop3", prop3);
+			}
+		}
+	}
+
+	/**
+	 * Create manager using the directory stub an the HTTPConnectorProvider
+	 */
+	ConnectedAssetAdministrationShellManager manager = new ConnectedAssetAdministrationShellManager(
+			// Add example specific mappings
+			new ExampleAASRegistry()
+					.addAASMapping("aas-001", "") // No AAS is provided in this example
+					.addSubmodelMapping("aas-001", "sm-001", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/SampleModel/submodel"),
+			// We connect via HTTP
+			new HTTPConnectorProvider());
+	
+	
+	
+	/**
+	 * VAB connection manager backend
+	 */
+	protected VABConnectionManager connManager = new VABConnectionManager(
+			// Add example specific mappings
+			new ExamplesPreconfiguredDirectory()
+			    // - VAB needs to know the relative path of the sub model that is defined by AAS meta model
+					.addMapping("sm-001VAB", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/SampleModel/submodel"),
+			// We connect via HTTP
+			new HTTPConnectorProvider());
+
+	
+	
+	/**
+	 * Instantiate and start context elements for this example. BaSyxDeployment contexts instantiate all
+	 * components on the IP address of the host. Therefore, all components use the same IP address. 
+	 */
+	@ClassRule
+	public static BaSyxDeployment context = new BaSyxDeployment(
+				// Servlets for example snippet
+				new BaSyxExamplesContext_Empty().
+					// Deploy example specific servlets to Tomcat server in this context
+					addServletMapping("/Testsuite/components/BaSys/1.0/SampleModel/*", new SubmodelServlet(new SampleSubModelFactory())));
+
+	
+	/**
+	 * Connect to sub model, query, and set property values
+	 */
+	@Test @SuppressWarnings("unchecked")
+	public void accessSubModel() throws Exception {
+		// Create and connect SDK connector
+		ISubModel subModel = manager.retrieveSubModel(new ModelUrn("aas-001"), new ModelUrn("sm-001"));
+		// - Retrieve sub model values and compare to expected values
+		assertTrue(subModel.getIdShort().equals("sm-001"));
+		assertTrue(subModel.getProperties().get("prop1").getIdShort().equals("prop1"));
+		assertTrue((int) subModel.getProperties().get("prop1").getValue() == 234);
+		assertTrue((int) subModel.getProperties().get("prop3").getValue() == 17);
+		assertTrue(subModel.getSubmodelElements().get("prop2").getIdShort().equals("prop2"));
+		assertTrue((int) ((ISubmodelElementCollection) subModel.getSubmodelElements().get("prop2")).getProperties().get("prop11").getValue() == 123);
+
+		// Connect to sub model using lower-level VAB interface
+		VABElementProxy connSubModel1 = this.connManager.connectToVABElement("sm-001VAB");
+		// - Read property values and compare with expected values
+		assertTrue((int) ((Map<String, Object>) connSubModel1.getModelPropertyValue(MultiSubmodelElementProvider.ELEMENTS + "/prop1")).get("value") == 234);
+		assertTrue((int) ((Map<String, Object>) connSubModel1.getModelPropertyValue(MultiSubmodelElementProvider.ELEMENTS + "/prop3")).get("value") == 17);
+		assertTrue(((Map<String, Object>) connSubModel1.getModelPropertyValue(MultiSubmodelElementProvider.ELEMENTS + "/prop1")).get("idShort").equals("prop1"));
+		assertTrue(((Map<String, Object>) connSubModel1.getModelPropertyValue(MultiSubmodelElementProvider.ELEMENTS + "/prop2")).get("idShort").equals("prop2"));
+		assertTrue((int) ((Map<String, Object>) connSubModel1.getModelPropertyValue("submodelElements/prop2/prop11")).get("value") == 123);
+		// - Change property value using VAB primitive
+		connSubModel1.setModelPropertyValue(MultiSubmodelElementProvider.ELEMENTS + "/prop1/value", 456);
+		// - Read value back using VAB primitive
+		assertTrue((int) ((Map<String, Object>) connSubModel1.getModelPropertyValue(MultiSubmodelElementProvider.ELEMENTS + "/prop1")).get("value") == 456);
+
+		// Read changed value back using SDK connector
+		assertTrue((int) subModel.getProperties().get("prop1").getValue() == 456);
+	}
+}
+
+
diff --git a/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/connection/servlet/AASServletConnectionFull.java b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/connection/servlet/AASServletConnectionFull.java
new file mode 100644
index 0000000..707398b
--- /dev/null
+++ b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/connection/servlet/AASServletConnectionFull.java
@@ -0,0 +1,150 @@
+package org.eclipse.basyx.examples.snippets.undoc.aas.connection.servlet;
+
+import static org.junit.Assert.assertTrue;
+
+import java.util.Map;
+
+import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
+import org.eclipse.basyx.components.servlet.submodel.SubmodelServlet;
+import org.eclipse.basyx.examples.contexts.BaSyxExamplesContext_Empty;
+import org.eclipse.basyx.examples.deployment.BaSyxDeployment;
+import org.eclipse.basyx.examples.support.directory.ExampleAASRegistry;
+import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
+import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElementCollection;
+import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.restapi.MultiSubmodelElementProvider;
+import org.eclipse.basyx.vab.manager.VABConnectionManager;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
+import org.junit.ClassRule;
+import org.junit.Test;
+
+
+
+/**
+ * Export sub model through a servlet and connect to that servlet
+ * 
+ * @author kuhn
+ *
+ */
+public class AASServletConnectionFull {
+
+	
+	/**
+	 * Example sub model. This example sub model is created with the BaSyx SDK factory and defines the AAS meta model properties
+	 */
+	static class SampleSubModelFactory extends SubModel {
+
+		/**
+		 * Constructor - create sub model property
+		 */
+		@SuppressWarnings("unchecked")
+		public SampleSubModelFactory() {
+			// Set sub model ID
+			setIdShort("sm-001");
+
+			// Add example properties
+			// - Add simple property
+			Property prop1 = new Property(234);
+			prop1.setIdShort("prop1");
+			addSubModelElement(prop1);
+
+			Property prop11 = new Property(123);
+			prop11.setIdShort("prop11");
+			// - Add container property that holds other properties
+			SubmodelElementCollection container = new SubmodelElementCollection();
+			container.setIdShort("prop2");
+			container.addSubModelElement(prop11);
+			// - Add container to property map
+			addSubModelElement(container);
+
+			// Add another property manually to sub model container "properties"
+			Property prop3 = new Property(17);
+			prop3.setIdShort("prop3");
+			{
+				((Map<String, Object>) this.get("submodelElements")).put("prop3", prop3);
+			}
+		}
+	}
+
+	/**
+	 * VAB connection manager backend
+	 */
+	protected VABConnectionManager connManager = new VABConnectionManager(
+			// Add example specific mappings
+			new ExamplesPreconfiguredDirectory()
+					// - VAB needs to know the relative path of the sub model that is defined by AAS
+					// meta model
+					.addMapping("sm-001VAB", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/SampleModel/submodel")
+					// - VAB needs to know the relative path of the sub model that is defined by AAS
+					// meta model
+					.addMapping("sm-001MVAB", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/SampleModelManual/submodel"),
+			// We connect via HTTP
+			new HTTPConnectorProvider());
+	
+	
+	
+	/**
+	 * VAB connection manager backend
+	 */
+	protected ConnectedAssetAdministrationShellManager manager = new ConnectedAssetAdministrationShellManager(
+			// Add example specific mappings
+			new ExampleAASRegistry()
+					.addAASMapping("aas-001", "") // no AAS is provided in this example
+					.addSubmodelMapping("aas-001", "sm-001", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/SampleModel/submodel"),
+			// We connect via HTTP
+			new HTTPConnectorProvider());
+
+	
+	
+	/**
+	 * Instantiate and start context elements for this example. BaSyxDeployment contexts instantiate all
+	 * components on the IP address of the host. Therefore, all components use the same IP address. 
+	 */
+	@ClassRule
+	public static BaSyxDeployment context = new BaSyxDeployment(
+				// Servlets for example snippet
+				new BaSyxExamplesContext_Empty().
+					// Deploy example specific servlets to Tomcat server in this context
+					addServletMapping("/Testsuite/components/BaSys/1.0/SampleModel/*", new SubmodelServlet(new SampleSubModelFactory())));
+
+	
+	/**
+	 * Connect to sub model, query, and set property values
+	 */
+	@Test @SuppressWarnings("unchecked")
+	public void accessSubModel() throws Exception {
+		// Create and connect SDK connector
+		ISubModel subModel = manager.retrieveSubModel(new ModelUrn("aas-001"), new ModelUrn("sm-001"));
+		// - Retrieve sub model values and compare to expected values
+		assertTrue(subModel.getIdShort().equals("sm-001"));
+		assertTrue(subModel.getProperties().get("prop1").getIdShort().equals("prop1"));
+		assertTrue((int) subModel.getProperties().get("prop1").getValue() == 234);
+		assertTrue((int) subModel.getProperties().get("prop3").getValue() == 17);
+		assertTrue(subModel.getSubmodelElements().get("prop2").getIdShort().equals("prop2"));
+		assertTrue((int) ((ISubmodelElementCollection) subModel.getSubmodelElements().get("prop2")).getProperties().get("prop11").getValue() == 123);
+
+
+		// Connect to sub model using lower-level VAB interface
+		VABElementProxy connSubModel1 = this.connManager.connectToVABElement("sm-001VAB");
+		// - Read property values and compare with expected values
+		assertTrue((int) ((Map<String, Object>) connSubModel1.getModelPropertyValue(MultiSubmodelElementProvider.ELEMENTS + "/prop1")).get("value") == 234);
+		assertTrue((int) ((Map<String, Object>) connSubModel1.getModelPropertyValue(MultiSubmodelElementProvider.ELEMENTS + "/prop3")).get("value") == 17);
+		assertTrue(((Map<String, Object>) connSubModel1.getModelPropertyValue(MultiSubmodelElementProvider.ELEMENTS + "/prop1")).get("idShort").equals("prop1"));
+		assertTrue(((Map<String, Object>) connSubModel1.getModelPropertyValue(MultiSubmodelElementProvider.ELEMENTS + "/prop2")).get("idShort").equals("prop2"));
+		assertTrue((int) ((Map<String, Object>) connSubModel1.getModelPropertyValue("submodelElements/prop2/prop11")).get("value") == 123);
+		// - Change property value using VAB primitive
+		connSubModel1.setModelPropertyValue(MultiSubmodelElementProvider.ELEMENTS + "/prop1/value", 456);
+		// - Read value back using VAB primitive
+		assertTrue((int) ((Map<String, Object>) connSubModel1.getModelPropertyValue(MultiSubmodelElementProvider.ELEMENTS + "/prop1")).get("value") == 456);
+
+		// Read changed value back using SDK connector
+		assertTrue((int) subModel.getProperties().get("prop1").getValue() == 456);
+	}
+}
+
+
diff --git a/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/connection/servlet/AASSubModelServletConnectorConnection.java b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/connection/servlet/AASSubModelServletConnectorConnection.java
new file mode 100644
index 0000000..59152d1
--- /dev/null
+++ b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/connection/servlet/AASSubModelServletConnectorConnection.java
@@ -0,0 +1,133 @@
+package org.eclipse.basyx.examples.snippets.undoc.aas.connection.servlet;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Map;
+
+import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
+import org.eclipse.basyx.components.servlet.submodel.SubmodelServlet;
+import org.eclipse.basyx.examples.contexts.BaSyxExamplesContext_Empty;
+import org.eclipse.basyx.examples.deployment.BaSyxDeployment;
+import org.eclipse.basyx.examples.support.directory.ExampleAASRegistry;
+import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
+import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElementCollection;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
+import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.vab.manager.VABConnectionManager;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
+import org.junit.ClassRule;
+import org.junit.Test;
+
+
+
+/**
+ * Export sub model through a servlet and connect to that servlet
+ * 
+ * @author kuhn
+ *
+ */
+public class AASSubModelServletConnectorConnection {
+
+	
+	/**
+	 * Example sub model. This example sub model is created with the BaSyx SDK factory and defines the AAS meta model properties
+	 */
+	static class SampleSubModel extends SubModel {
+		/**
+		 * Constructor - create sub model property
+		 */
+		@SuppressWarnings("unchecked")
+		public SampleSubModel() {
+			// Set sub model ID
+			setIdShort("sm-001");
+
+			// Add example properties
+			// - Add simple property
+			Property prop1 = new Property(234);
+			prop1.setIdShort("prop1");
+			addSubModelElement(prop1);
+
+			Property prop11 = new Property(123);
+			prop11.setIdShort("prop11");
+			// - Add container property that holds other properties
+			SubmodelElementCollection container = new SubmodelElementCollection();
+			container.setIdShort("prop2");
+			container.addSubModelElement(prop11);
+			// - Add container to property map
+			addSubModelElement(container);
+
+			// Add another property manually to sub model container "properties"
+			Property prop3 = new Property(17);
+			prop3.setIdShort("prop3");
+			{
+				((Map<String, Object>) this.get("submodelElements")).put("prop3", prop3);
+			}
+		}
+	}
+	
+	/**
+	 * Create manager using the directory stub an the HTTPConnectorProvider
+	 */
+	ConnectedAssetAdministrationShellManager manager = new ConnectedAssetAdministrationShellManager(
+			// Add example specific mappings
+			new ExampleAASRegistry()
+			    // - SDK connectors encapsulate relative path to sub model (/aas/submodels/sm-001)
+					.addAASMapping("aas-001", "") // No AAS is provided in this example
+					.addSubmodelMapping("aas-001", "sm-001", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/SampleModel/submodel"),
+			// We connect via HTTP
+			new HTTPConnectorProvider());
+
+	/**
+	 * VAB connection manager backend
+	 */
+	protected VABConnectionManager connManager = new VABConnectionManager(
+			// Add example specific mappings
+			new ExamplesPreconfiguredDirectory()
+			    // - VAB needs to know the relative path of the sub model that is defined by AAS meta model
+					.addMapping("sm-001VAB", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/SampleModel/aas/submodels/sm-001/submodel"),
+			// We connect via HTTP
+			new HTTPConnectorProvider());
+
+	
+	
+	/**
+	 * Instantiate and start context elements for this example. BaSyxDeployment contexts instantiate all
+	 * components on the IP address of the host. Therefore, all components use the same IP address. 
+	 */
+	@ClassRule
+	public static BaSyxDeployment context = new BaSyxDeployment(
+				// Servlets for example snippet
+				new BaSyxExamplesContext_Empty().
+					// Deploy example specific servlets to Tomcat server in this context
+					addServletMapping("/Testsuite/components/BaSys/1.0/SampleModel/*",       new SubmodelServlet(new SampleSubModel()))
+			);
+
+	
+	/**
+	 * Application code: Connect to sub model, query, and set property values
+	 */
+	@Test
+	public void accessSubModel() throws Exception {
+		
+		// Create and connect SDK connector
+		ISubModel subModel = manager.retrieveSubModel(new ModelUrn("aas-001"), new ModelUrn("sm-001"));
+		
+		// - Retrieve sub model values and compare to expected values
+		assertTrue(subModel.getIdShort().equals("sm-001"));
+		assertTrue(subModel.getProperties().get("prop1").getIdShort().equals("prop1"));
+		assertTrue((int) subModel.getProperties().get("prop1").getValue() == 234);
+		assertTrue((int) subModel.getProperties().get("prop3").getValue() == 17);
+
+		ISubmodelElementCollection prop2 = (ISubmodelElementCollection) subModel.getSubmodelElements().get("prop2");
+		assertEquals("prop2", prop2.getIdShort());
+		Map<String, IProperty> properties = prop2.getProperties();
+		assertEquals(123, properties.get("prop11").getValue());
+	}
+}
+
+
diff --git a/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/connection/servlet/AASSubModelServletVABConnection.java b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/connection/servlet/AASSubModelServletVABConnection.java
new file mode 100644
index 0000000..6e4e498
--- /dev/null
+++ b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/connection/servlet/AASSubModelServletVABConnection.java
@@ -0,0 +1,118 @@
+package org.eclipse.basyx.examples.snippets.undoc.aas.connection.servlet;
+
+import static org.junit.Assert.assertTrue;
+
+import java.util.Map;
+
+import org.eclipse.basyx.components.servlet.submodel.SubmodelServlet;
+import org.eclipse.basyx.examples.contexts.BaSyxExamplesContext_Empty;
+import org.eclipse.basyx.examples.deployment.BaSyxDeployment;
+import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
+import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.restapi.MultiSubmodelElementProvider;
+import org.eclipse.basyx.vab.manager.VABConnectionManager;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
+import org.junit.ClassRule;
+import org.junit.Test;
+
+
+
+/**
+ * Export sub model through a servlet and connect to that servlet
+ * 
+ * @author kuhn
+ *
+ */
+public class AASSubModelServletVABConnection {
+
+
+	/** 
+	 * Example sub model. This example sub model is created with the BaSyx SDK factory and defines the AAS meta model properties
+	 */
+	static class SampleSubModel extends SubModel {
+		/**
+		 * Constructor - create sub model property
+		 */
+		@SuppressWarnings("unchecked")
+		public SampleSubModel() {
+			// Set sub model ID
+			setIdShort("sm-001");
+
+			// Add example properties
+			// - Add simple property
+			Property prop1 = new Property(234);
+			prop1.setIdShort("prop1");
+			addSubModelElement(prop1);
+
+			Property prop11 = new Property(123);
+			prop11.setIdShort("prop11");
+			// - Add container property that holds other properties
+			SubmodelElementCollection container = new SubmodelElementCollection();
+			container.setIdShort("prop2");
+			container.addSubModelElement(prop11);
+			// - Add container to property map
+			addSubModelElement(container);
+
+			// Add another property manually to sub model container "properties"
+			Property prop3 = new Property(17);
+			prop3.setIdShort("prop3");
+			{
+				((Map<String, Object>) this.get("submodelElements")).put("prop3", prop3);
+			}
+		}
+	}
+	
+	
+	
+	/**
+	 * VAB connection manager backend
+	 */
+	protected VABConnectionManager connManager = new VABConnectionManager(
+			// Add example specific mappings
+			new ExamplesPreconfiguredDirectory()
+					// Entries map directly at the SubmodelServlet
+					.addMapping("aas-001", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/SampleModel/submodel")
+					.addMapping("sm-001", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/SampleModel/submodel")
+					.addMapping("sm-001VAB", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/SampleModel/submodel"),
+			// We connect via HTTP
+			new HTTPConnectorProvider());
+
+	
+	
+	/**
+	 * Instantiate and start context elements for this example. BaSyxDeployment contexts instantiate all
+	 * components on the IP address of the host. Therefore, all components use the same IP address. 
+	 */
+	@ClassRule
+	public static BaSyxDeployment context = new BaSyxDeployment(
+				// Servlets for example snippet
+				new BaSyxExamplesContext_Empty().
+					// Deploy example specific servlets to Tomcat server in this context
+					addServletMapping("/Testsuite/components/BaSys/1.0/SampleModel/*",       new SubmodelServlet(new SampleSubModel()))
+			);
+
+	
+	/**
+	 * Connect to sub model, query, and set property values
+	 */
+	@Test @SuppressWarnings("unchecked")
+	public void accessSubModel() throws Exception {
+		// Connect to sub model using lower-level VAB interface
+		VABElementProxy connSubModel1 = this.connManager.connectToVABElement("sm-001VAB");
+		// - Read property values and compare with expected values
+		assertTrue((int) ((Map<String, Object>) connSubModel1.getModelPropertyValue(MultiSubmodelElementProvider.ELEMENTS + "/prop1")).get("value") == 234);
+		assertTrue((int) ((Map<String, Object>) connSubModel1.getModelPropertyValue(MultiSubmodelElementProvider.ELEMENTS + "/prop3")).get("value") == 17);
+		assertTrue(((Map<String, Object>) connSubModel1.getModelPropertyValue(MultiSubmodelElementProvider.ELEMENTS + "/prop1")).get("idShort").equals("prop1"));
+		assertTrue(((Map<String, Object>) connSubModel1.getModelPropertyValue(MultiSubmodelElementProvider.ELEMENTS + "/prop2")).get("idShort").equals("prop2"));
+		assertTrue((Integer) connSubModel1.getModelPropertyValue("submodelElements/prop2/prop11/value") == 123);
+		// - Change property value using VAB primitive
+		connSubModel1.setModelPropertyValue(MultiSubmodelElementProvider.ELEMENTS + "/prop1/value", 456);
+		// - Read value back using VAB primitive
+		assertTrue((Integer) connSubModel1.getModelPropertyValue(MultiSubmodelElementProvider.ELEMENTS + "/prop1/value") == 456);
+	}
+}
+
+
diff --git a/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/dynamic/RunAASDynamicOperationSnippet.java b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/dynamic/RunAASDynamicOperationSnippet.java
new file mode 100644
index 0000000..bd0243c
--- /dev/null
+++ b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/dynamic/RunAASDynamicOperationSnippet.java
@@ -0,0 +1,106 @@
+package org.eclipse.basyx.examples.snippets.undoc.aas.dynamic;
+
+import static org.junit.Assert.assertTrue;
+
+import java.io.Serializable;
+import java.util.Map;
+import java.util.function.Supplier;
+
+import org.eclipse.basyx.components.servlet.vab.VABLambdaServlet;
+import org.eclipse.basyx.examples.contexts.BaSyxExamplesContext;
+import org.eclipse.basyx.examples.deployment.BaSyxDeployment;
+import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
+import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.vab.manager.VABConnectionManager;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaProviderHelper;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
+import org.junit.ClassRule;
+import org.junit.Test;
+
+
+
+/**
+ * Illustrate the dynamic deployment of AAS operations
+ * 
+ * @author kuhn
+ *
+ */
+public class RunAASDynamicOperationSnippet {
+
+	
+	/**
+	 * VAB connection manager backend
+	 */
+	protected VABConnectionManager connManager = new VABConnectionManager(
+			new ExamplesPreconfiguredDirectory()
+				// Add example specific mappings
+			    .addMapping("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003",  "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/devicestatusVAB/"),
+			new HTTPConnectorProvider());
+
+	
+	/**
+	 * Instantiate and start context elements for this example. BaSyxDeployment contexts instantiate all
+	 * components on the IP address of the host. Therefore, all components use the same IP address. 
+	 */
+	@ClassRule
+	public static BaSyxDeployment context = new BaSyxDeployment(
+				// Simulated servlets
+				// - BaSys topology with one AAS Server and one SQL directory
+				new BaSyxExamplesContext().
+					// Deploy example specific servlets to Tomcat server in this context
+					addServletMapping("/Testsuite/components/BaSys/1.0/devicestatusVAB/*", new VABLambdaServlet())
+			);
+
+	
+	
+	
+	/**
+	 * Test basic queries
+	 */
+	@Test
+	public void snippet() throws Exception {
+
+		// Server connections
+		// - Connect to device (VAB object)
+		VABElementProxy connSubModel1 = this.connManager.connectToVABElement("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003");
+
+		
+		// Create properties on AAS
+
+		// - Add example properties
+		SubModel submodel = new SubModel();
+		submodel.setIdShort("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003");
+		Property prop1 = new Property(7);
+		prop1.setIdShort("prop1");
+		submodel.addSubModelElement(prop1);
+
+		Property prop2 = new Property("myStr");
+		prop2.setIdShort("prop2");
+		submodel.addSubModelElement(prop2);
+		// - Transfer sub model to server
+		connSubModel1.setModelPropertyValue("/", submodel);
+
+		
+		// Read property values
+		String prop2Val = (String) connSubModel1.getModelPropertyValue("submodelElements/prop2/value");
+		// - Check property values
+		assertTrue(prop2Val.equals("myStr"));
+
+		
+		// Create dynamic get/set operation as lambda expression
+		Map<String, Object> dynamicPropertyVal = VABLambdaProviderHelper.createSimple((Supplier<Object> & Serializable) () -> {
+			return "dynamicExampleValue";
+		}, null);
+		// - Update property properties/dynamicExample with dynamic get/set operation
+		connSubModel1.setModelPropertyValue("submodelElements/prop2/value", dynamicPropertyVal);
+
+		
+		// Read dynamicExample property
+		prop2Val = (String) connSubModel1.getModelPropertyValue("submodelElements/prop2/value");
+		// - Check property values
+		assertTrue(prop2Val.equals("dynamicExampleValue"));
+	}
+}
+
diff --git a/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/dynamic/RunAASManualHTTPOperationsSnippet.java b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/dynamic/RunAASManualHTTPOperationsSnippet.java
new file mode 100644
index 0000000..3be7c43
--- /dev/null
+++ b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/dynamic/RunAASManualHTTPOperationsSnippet.java
@@ -0,0 +1,99 @@
+package org.eclipse.basyx.examples.snippets.undoc.aas.dynamic;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Map;
+
+import org.eclipse.basyx.components.servlet.vab.VABLambdaServlet;
+import org.eclipse.basyx.examples.contexts.BaSyxExamplesContext;
+import org.eclipse.basyx.examples.deployment.BaSyxDeployment;
+import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
+import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.tools.webserviceclient.WebServiceJSONClient;
+import org.eclipse.basyx.vab.manager.VABConnectionManager;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
+import org.junit.ClassRule;
+import org.junit.Test;
+
+
+
+/**
+ * Illustrate the use of AAS operations using HTTP REST calls
+ * 
+ * @author kuhn
+ *
+ */
+public class RunAASManualHTTPOperationsSnippet {
+
+	
+	/**
+	 * VAB connection manager backend
+	 */
+	protected VABConnectionManager connManager = new VABConnectionManager(
+			new ExamplesPreconfiguredDirectory()
+				// Add example specific mappings
+			    .addMapping("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003",  "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/devicestatusVAB/"),
+			new HTTPConnectorProvider());
+
+	
+	/**
+	 * Instantiate and start context elements for this example. BaSyxDeployment contexts instantiate all
+	 * components on the IP address of the host. Therefore, all components use the same IP address. 
+	 */
+	@ClassRule
+	public static BaSyxDeployment context = new BaSyxDeployment(
+				// Simulated servlets
+				// - BaSys topology with one AAS Server and one SQL directory
+				new BaSyxExamplesContext().
+					// Deploy example specific servlets to Tomcat server in this context
+					addServletMapping("/Testsuite/components/BaSys/1.0/devicestatusVAB/*", new VABLambdaServlet())
+			);
+
+	
+	
+	
+	/**
+	 * Test basic queries
+	 */
+	@Test @SuppressWarnings("unchecked")
+	public void snippet() throws Exception {
+
+		// Server connections
+		// - Connect to device (VAB object)
+		VABElementProxy connSubModel1 = this.connManager.connectToVABElement("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003");
+
+		int prop1Val = 7;
+		String prop1IdShort = "prop1";
+		String prop2Val = "myStr";
+		// Add example properties
+		SubModel submodel = new SubModel();
+		submodel.setIdShort("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003");
+		Property prop1 = new Property(prop1Val);
+		prop1.setIdShort(prop1IdShort);
+		submodel.addSubModelElement(prop1);
+
+		Property prop2 = new Property(prop2Val);
+		prop2.setIdShort("prop2");
+		submodel.addSubModelElement(prop2);
+
+		// Transfer sub model to server
+		connSubModel1.setModelPropertyValue("/", submodel);
+		
+		// Web service client accesses AAS using HTTP REST calls
+		WebServiceJSONClient jsonClient = new WebServiceJSONClient();
+		
+		// Read property values
+		// - Use WebServiceJSONClient class. Returned property contains meta data. The actual property is stored in property "entity", property value is in entity property "value"
+		int retrievedProp1Val = (int) ((Map<String, Object>) jsonClient.get("http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/devicestatusVAB/submodelElements/prop1")).get("value");
+		String retrievedProp1Id = (String) ((Map<String, Object>) jsonClient.get("http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/devicestatusVAB/submodelElements/prop1")).get("idShort");
+		String retrievedProp2Val = (String) ((Map<String, Object>) jsonClient.get("http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/devicestatusVAB/submodelElements/prop2")).get("value");
+		
+		// Check results
+		assertEquals(prop1Val, retrievedProp1Val);
+		assertEquals(prop1IdShort, retrievedProp1Id);
+		assertEquals(prop2Val, retrievedProp2Val);
+	}
+}
+
diff --git a/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/dynamic/RunAASPropertiesCRUDAccessSnippet.java b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/dynamic/RunAASPropertiesCRUDAccessSnippet.java
new file mode 100644
index 0000000..8f7d879
--- /dev/null
+++ b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/dynamic/RunAASPropertiesCRUDAccessSnippet.java
@@ -0,0 +1,114 @@
+package org.eclipse.basyx.examples.snippets.undoc.aas.dynamic;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import org.eclipse.basyx.components.servlet.vab.VABLambdaServlet;
+import org.eclipse.basyx.examples.contexts.BaSyxExamplesContext;
+import org.eclipse.basyx.examples.deployment.BaSyxDeployment;
+import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
+import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.eclipse.basyx.vab.manager.VABConnectionManager;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
+import org.junit.ClassRule;
+import org.junit.Test;
+
+
+
+/**
+ * Illustrate the use of AAS operations
+ * 
+ * @author kuhn
+ *
+ */
+public class RunAASPropertiesCRUDAccessSnippet {
+
+	
+	/**
+	 * VAB connection manager backend
+	 */
+	protected VABConnectionManager connManager = new VABConnectionManager(
+			new ExamplesPreconfiguredDirectory()
+				// Add example specific mappings
+			    .addMapping("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003",  "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/devicestatusVAB/"),
+			new HTTPConnectorProvider());
+
+	
+	/**
+	 * Instantiate and start context elements for this example. BaSyxDeployment contexts instantiate all
+	 * components on the IP address of the host. Therefore, all components use the same IP address. 
+	 */
+	@ClassRule
+	public static BaSyxDeployment context = new BaSyxDeployment(
+				// Simulated servlets
+				// - BaSys topology with one AAS Server and one SQL directory
+				new BaSyxExamplesContext().
+					// Deploy example specific servlets to Tomcat server in this context
+					addServletMapping("/Testsuite/components/BaSys/1.0/devicestatusVAB/*", new VABLambdaServlet())
+			);
+
+	
+	
+	
+	/**
+	 * Test basic queries
+	 */
+	@Test
+	public void snippet() throws Exception {
+
+		// Server connections
+		// - Connect to device (VAB object)
+		VABElementProxy connSubModel1 = this.connManager.connectToVABElement("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003");
+
+		
+		// Create properties on AAS
+		// - Add example properties
+		SubModel submodel = new SubModel();
+		submodel.setIdShort("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003");
+		Property prop1 = new Property(7);
+		prop1.setIdShort("prop1");
+		submodel.addSubModelElement(prop1);
+
+		Property prop2 = new Property("myStr");
+		prop2.setIdShort("prop2");
+		submodel.addSubModelElement(prop2);
+		// - Transfer sub model to server
+		connSubModel1.setModelPropertyValue("/", submodel);
+		
+		// Read property values
+		int prop1Val = (int) connSubModel1.getModelPropertyValue("submodelElements/prop1/value");
+		String prop2Val = (String) connSubModel1.getModelPropertyValue("submodelElements/prop2/value");
+		// - Check property values
+		assertTrue(prop1Val == 7);
+		assertTrue(prop2Val.equals("myStr"));
+		
+		// Update property values
+		connSubModel1.setModelPropertyValue("submodelElements/prop1/value", 8);
+		connSubModel1.setModelPropertyValue("submodelElements/prop2/value", "stillMine");
+		
+		// Read property values again
+		prop1Val = (int) connSubModel1.getModelPropertyValue("submodelElements/prop1/value");
+		prop2Val = (String) connSubModel1.getModelPropertyValue("submodelElements/prop2/value");
+		// - Check property values
+		assertTrue(prop1Val == 8);
+		assertTrue(prop2Val.equals("stillMine"));
+
+		// Delete property values
+		connSubModel1.deleteValue("submodelElements/prop1");
+		connSubModel1.deleteValue("submodelElements/prop2");
+		
+		// Read property values again
+		try {
+			connSubModel1.getModelPropertyValue("submodelElements/prop1");
+			fail();
+		} catch (ResourceNotFoundException e) {}
+		try {
+			connSubModel1.getModelPropertyValue("submodelElements/prop2");
+			fail();
+		} catch (ResourceNotFoundException e) {}
+	}
+}
+
diff --git a/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/dynamic/RunAASTailoredSupplierSnippet.java b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/dynamic/RunAASTailoredSupplierSnippet.java
new file mode 100644
index 0000000..d08cd3b
--- /dev/null
+++ b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/dynamic/RunAASTailoredSupplierSnippet.java
@@ -0,0 +1,141 @@
+package org.eclipse.basyx.examples.snippets.undoc.aas.dynamic;
+
+import static org.junit.Assert.assertTrue;
+
+import java.io.Serializable;
+import java.util.Map;
+import java.util.function.Supplier;
+
+import org.eclipse.basyx.components.servlet.vab.VABLambdaServlet;
+import org.eclipse.basyx.examples.contexts.BaSyxExamplesContext;
+import org.eclipse.basyx.examples.deployment.BaSyxDeployment;
+import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
+import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.vab.manager.VABConnectionManager;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaProviderHelper;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
+import org.junit.ClassRule;
+import org.junit.Test;
+
+
+
+/**
+ * Example for a tailored BaSyx supplier
+ * 
+ * - BaSyx will serialize this class (and all contained references) and transmit it to the AAS server
+ * 
+ * @author kuhn
+ *
+ */
+class TailoredBaSyxSupplier implements Supplier<Object>, Serializable {
+
+	/**
+	 * Version number of serialized instances
+	 */
+	private static final long serialVersionUID = 1L;
+
+
+	/**
+	 * Return value
+	 */
+	@Override
+	public Object get() {
+		// Delegate call to tailored BaSyx supplier base class
+		return getInternal();
+	}
+
+	
+	/**
+	 * Example function of tailored BaSyx supplier base class
+	 */
+	protected String getInternal() {
+		return "BaSyxSupplier!";
+	}
+}
+
+
+
+
+/**
+ * Illustrate the dynamic deployment of AAS operations with a tailored consumer
+ * 
+ * @author kuhn
+ *
+ */
+public class RunAASTailoredSupplierSnippet {
+
+	
+	/**
+	 * VAB connection manager backend
+	 */
+	protected VABConnectionManager connManager = new VABConnectionManager(
+			new ExamplesPreconfiguredDirectory()
+				// Add example specific mappings
+			    .addMapping("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003",  "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/devicestatusVAB/"),
+			new HTTPConnectorProvider());
+
+	
+	/**
+	 * Instantiate and start context elements for this example. BaSyxDeployment contexts instantiate all
+	 * components on the IP address of the host. Therefore, all components use the same IP address. 
+	 */
+	@ClassRule
+	public static BaSyxDeployment context = new BaSyxDeployment(
+				// Simulated servlets
+				// - BaSys topology with one AAS Server and one SQL directory
+				new BaSyxExamplesContext().
+					// Deploy example specific servlets to Tomcat server in this context
+					addServletMapping("/Testsuite/components/BaSys/1.0/devicestatusVAB/*", new VABLambdaServlet())
+			);
+
+		
+	
+	/**
+	 * Test basic queries
+	 */
+	@Test
+	public void snippet() throws Exception {
+
+		// Server connections
+		// - Connect to device (VAB object)
+		VABElementProxy connSubModel1 = this.connManager.connectToVABElement("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003");
+
+		
+		// Create properties on AAS
+
+		// - Add example properties
+		SubModel submodel = new SubModel();
+		submodel.setIdShort("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003");
+		Property prop1 = new Property(7);
+		prop1.setIdShort("prop1");
+		submodel.addSubModelElement(prop1);
+
+		Property prop2 = new Property("myStr");
+		prop2.setIdShort("prop2");
+		submodel.addSubModelElement(prop2);
+
+		// - Transfer sub model to server
+		connSubModel1.setModelPropertyValue("/", submodel);
+
+		
+		// Read property values
+		String prop2Val = (String) connSubModel1.getModelPropertyValue("submodelElements/prop2/value");
+		// - Check property values
+		assertTrue(prop2Val.equals("myStr"));
+
+		
+		// Create dynamic get/set operation as lambda expression
+		Map<String, Object> dynamicPropertyVal = VABLambdaProviderHelper.createSimple(new TailoredBaSyxSupplier(), null);
+		// - Update property properties/dynamicExample with dynamic get/set operation
+		connSubModel1.setModelPropertyValue("submodelElements/prop2/value", dynamicPropertyVal);
+
+		// Read dynamicExample property
+		prop2Val = (String) connSubModel1.getModelPropertyValue("submodelElements/prop2/value");
+
+		// - Check value
+		assertTrue(prop2Val.equals("BaSyxSupplier!"));
+	}
+}
+
diff --git a/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/vab/connection/RunAASManualHTTPOperationsSnippet.java b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/vab/connection/RunAASManualHTTPOperationsSnippet.java
new file mode 100644
index 0000000..b643870
--- /dev/null
+++ b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/vab/connection/RunAASManualHTTPOperationsSnippet.java
@@ -0,0 +1,81 @@
+package org.eclipse.basyx.examples.snippets.undoc.vab.connection;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.HashMap;
+
+import org.eclipse.basyx.components.servlet.vab.VABLambdaServlet;
+import org.eclipse.basyx.examples.contexts.BaSyxExamplesContext;
+import org.eclipse.basyx.examples.deployment.BaSyxDeployment;
+import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
+import org.eclipse.basyx.tools.webserviceclient.WebServiceJSONClient;
+import org.eclipse.basyx.vab.manager.VABConnectionManager;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
+import org.junit.ClassRule;
+
+
+
+/**
+ * Illustrate the use of AAS operations using HTTP REST calls
+ * 
+ * @author kuhn
+ *
+ */
+public class RunAASManualHTTPOperationsSnippet {
+
+	
+	/**
+	 * VAB connection manager backend
+	 */
+	protected VABConnectionManager connManager = new VABConnectionManager(
+			new ExamplesPreconfiguredDirectory()
+				// Add example specific mappings
+			    .addMapping("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003",  "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/devicestatusVAB/"),
+			new HTTPConnectorProvider());
+
+	
+	/**
+	 * Instantiate and start context elements for this example. BaSyxDeployment contexts instantiate all
+	 * components on the IP address of the host. Therefore, all components use the same IP address. 
+	 */
+	@ClassRule
+	public static BaSyxDeployment context = new BaSyxDeployment(
+				// Simulated servlets
+				// - BaSys topology with one AAS Server and one SQL directory
+				new BaSyxExamplesContext().
+					// Deploy example specific servlets to Tomcat server in this context
+					addServletMapping("/Testsuite/components/BaSys/1.0/devicestatusVAB/*", new VABLambdaServlet())
+			);
+
+	
+	
+	
+	/**
+	 * Test basic queries
+	 */
+	public void snippet() throws Exception {
+
+		// Server connections
+		// - Connect to device (VAB object)
+		VABElementProxy connSubModel1 = this.connManager.connectToVABElement("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003");
+
+		int prop1Val = 7;
+		String prop2Val = "myStr";
+		// Create properties on AAS using connection
+		connSubModel1.createValue("properties", new HashMap<String, Object>());
+		connSubModel1.createValue("properties/prop1", prop1Val);
+		connSubModel1.createValue("properties/prop2", prop2Val);
+		
+		
+		// Web service client accesses AAS using HTTP REST calls
+		WebServiceJSONClient jsonClient = new WebServiceJSONClient();
+		
+		
+		// Read property values
+		// - Use WebServiceJSONClient class. Returned property contains meta data. The actual value is stored in property "entity"
+		assertEquals(prop1Val, jsonClient.get("http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/devicestatusVAB/properties/prop1"));
+		assertEquals(prop2Val, jsonClient.get("http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/devicestatusVAB/properties/prop2"));
+	}
+}
+
diff --git a/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/vab/connection/RunAASPropertiesSnippet.java b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/vab/connection/RunAASPropertiesSnippet.java
new file mode 100644
index 0000000..730cfd5
--- /dev/null
+++ b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/vab/connection/RunAASPropertiesSnippet.java
@@ -0,0 +1,99 @@
+package org.eclipse.basyx.examples.snippets.undoc.vab.connection;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.HashMap;
+
+import org.eclipse.basyx.components.servlet.vab.VABLambdaServlet;
+import org.eclipse.basyx.examples.contexts.BaSyxExamplesContext;
+import org.eclipse.basyx.examples.deployment.BaSyxDeployment;
+import org.eclipse.basyx.examples.support.directory.ExamplesPreconfiguredDirectory;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.eclipse.basyx.vab.manager.VABConnectionManager;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
+import org.junit.ClassRule;
+import org.junit.Test;
+
+
+
+/**
+ * Illustrate the use of AAS operations
+ * 
+ * @author kuhn
+ *
+ */
+public class RunAASPropertiesSnippet {
+
+	
+	/**
+	 * VAB connection manager backend
+	 */
+	protected VABConnectionManager connManager = new VABConnectionManager(
+			new ExamplesPreconfiguredDirectory()
+				// Add example specific mappings
+			    .addMapping("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003",  "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/devicestatusVAB/"),
+			new HTTPConnectorProvider());
+
+	
+	/**
+	 * Instantiate and start context elements for this example. BaSyxDeployment contexts instantiate all
+	 * components on the IP address of the host. Therefore, all components use the same IP address. 
+	 */
+	@ClassRule
+	public static BaSyxDeployment context = new BaSyxDeployment(
+				// Simulated servlets
+				// - BaSys topology with one AAS Server and one SQL directory
+				new BaSyxExamplesContext().
+					// Deploy example specific servlets to Tomcat server in this context
+					addServletMapping("/Testsuite/components/BaSys/1.0/devicestatusVAB/*", new VABLambdaServlet())
+			);
+
+	
+	
+	
+	/**
+	 * Test basic queries
+	 */
+	@Test
+	public void snippet() throws Exception {
+
+		// Server connections
+		// - Connect to device (VAB object)
+		VABElementProxy connSubModel1 = this.connManager.connectToVABElement("urn:de.FHG:devices.es.iese:statusSM:1.0:3:x-509#003");
+
+		
+		// Create properties on AAS
+		connSubModel1.createValue("properties", new HashMap<String, Object>());
+		connSubModel1.createValue("properties/prop1", 7);
+		connSubModel1.createValue("properties/prop2", "myStr");
+		
+		// Read property values
+		assertTrue((int) connSubModel1.getModelPropertyValue("properties/prop1") == 7);
+		assertTrue(connSubModel1.getModelPropertyValue("properties/prop2").equals("myStr"));
+		
+		// Update property values
+		connSubModel1.setModelPropertyValue("properties/prop1", 8);
+		connSubModel1.setModelPropertyValue("properties/prop2", "stillMine");
+		
+		// Read property values again
+		assertTrue((int) connSubModel1.getModelPropertyValue("properties/prop1") == 8);
+		assertTrue(connSubModel1.getModelPropertyValue("properties/prop2").equals("stillMine"));
+
+		// Delete property values
+		connSubModel1.deleteValue("properties/prop1");
+		connSubModel1.deleteValue("properties/prop2");
+		
+		// Read property values again
+		try {
+			connSubModel1.getModelPropertyValue("properties/prop1");
+			fail();
+		} catch (ResourceNotFoundException e) {}
+		try {
+			connSubModel1.getModelPropertyValue("properties/prop2");
+			fail();
+		} catch (ResourceNotFoundException e) {}
+	}
+}
+
diff --git a/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/cfgprovider/TestCFGProvider.java b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/cfgprovider/TestCFGProvider.java
new file mode 100644
index 0000000..ffa29dc
--- /dev/null
+++ b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/cfgprovider/TestCFGProvider.java
@@ -0,0 +1,68 @@
+package org.eclipse.basyx.sandbox.regression.components.cfgprovider;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Map;
+
+import org.eclipse.basyx.regression.support.directory.ComponentsTestsuiteDirectory;
+import org.eclipse.basyx.regression.support.server.context.ComponentsRegressionContext;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
+import org.eclipse.basyx.testsuite.regression.vab.protocol.http.AASHTTPServerResource;
+import org.eclipse.basyx.vab.manager.VABConnectionManager;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
+import org.junit.ClassRule;
+import org.junit.Test;
+
+
+/**
+ * Test queries to CFG file provider
+ * 
+ * @author kuhn
+ *
+ */
+public class TestCFGProvider {
+
+	
+	/**
+	 * VAB connection manager backend
+	 */
+	protected VABConnectionManager connManager = new VABConnectionManager(new ComponentsTestsuiteDirectory(), new HTTPConnectorProvider());
+
+
+	/** 
+	 * Makes sure Tomcat Server is started with basyx.components regression test case
+	 */
+	@ClassRule
+	public static AASHTTPServerResource res = new AASHTTPServerResource(new ComponentsRegressionContext());
+	
+	
+	/**
+	 * Test basic queries
+	 */
+	@SuppressWarnings("unchecked")
+	@Test
+	public void test() throws Exception {
+		// Connect to sub model "CfgFileTestAAS"
+		VABElementProxy connSubModel = this.connManager.connectToVABElement("CfgFileTestAAS");
+
+		
+		// Get property value
+		Map<String, Object> value1 = (Map<String, Object>) connSubModel
+				.getModelPropertyValue("/aas/submodels/sampleCFG/" + SubmodelElementProvider.PROPERTIES + "/cfgProperty1/value");
+
+		assertEquals("exampleStringValue", value1.get(Property.VALUE));
+
+		
+		// Get property value
+		Map<String, Object> value2 = (Map<String, Object>) connSubModel
+				.getModelPropertyValue("/aas/submodels/sampleCFG/" + SubmodelElementProvider.PROPERTIES + "/cfgProperty2/value");
+		assertEquals("12", value2.get(Property.VALUE));
+
+		// Get property value
+		Map<String, Object> value3 = (Map<String, Object>) connSubModel
+				.getModelPropertyValue("/aas/submodels/sampleCFG/" + SubmodelElementProvider.PROPERTIES + "/cfgProperty3/value");
+		assertEquals("45.8", value3.get(Property.VALUE));
+	}
+}
diff --git a/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/cfgprovider/TestCFGProviderPropertyMetaData.java b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/cfgprovider/TestCFGProviderPropertyMetaData.java
new file mode 100644
index 0000000..22f824e
--- /dev/null
+++ b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/cfgprovider/TestCFGProviderPropertyMetaData.java
@@ -0,0 +1,75 @@
+package org.eclipse.basyx.sandbox.regression.components.cfgprovider;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Collection;
+import java.util.Map;
+
+import org.eclipse.basyx.regression.support.directory.ComponentsTestsuiteDirectory;
+import org.eclipse.basyx.regression.support.server.context.ComponentsRegressionContext;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangStrings;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
+import org.eclipse.basyx.testsuite.regression.vab.protocol.http.AASHTTPServerResource;
+import org.eclipse.basyx.vab.manager.VABConnectionManager;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
+import org.junit.ClassRule;
+import org.junit.Test;
+
+/**
+ * Test queries to CFG file provider
+ * 
+ * @author kuhn
+ *
+ */
+public class TestCFGProviderPropertyMetaData {
+
+	/**
+	 * VAB connection manager backend
+	 */
+	protected VABConnectionManager connManager = new VABConnectionManager(new ComponentsTestsuiteDirectory(),
+			new HTTPConnectorProvider());
+
+	/**
+	 * Makes sure Tomcat Server is started
+	 */
+	@ClassRule
+	public static AASHTTPServerResource res = new AASHTTPServerResource(new ComponentsRegressionContext());
+
+	/**
+	 * Test basic queries
+	 */
+	@SuppressWarnings("unchecked")
+	@Test
+	public void test() throws Exception {
+
+		// Connect to sub model "CfgFileTestAAS"
+		VABElementProxy connSubModel = this.connManager.connectToVABElement("CfgFileTestAAS");
+
+		// Get property value
+		Map<String, Object> value1 = (Map<String, Object>) connSubModel
+				.getModelPropertyValue("/aas/submodels/sampleCFG/" + SubmodelElementProvider.PROPERTIES + "/cfgProperty1");
+		assertEquals("exampleStringValue", value1.get(Property.VALUE));
+		// - Check property meta data (description)
+		Map<String, Object> value1a = (Map<String, Object>) connSubModel
+				.getModelPropertyValue("/aas/submodels/sampleCFG/" + SubmodelElementProvider.PROPERTIES + "/cfgProperty1");
+		LangStrings description = LangStrings.createAsFacade((Collection<Map<String, Object>>) value1a.get("description"));
+		assertEquals("Configuration property description", description.get(""));
+
+		// Get property value
+		Map<String, Object> value2 = (Map<String, Object>) connSubModel
+				.getModelPropertyValue("/aas/submodels/sampleCFG/" + SubmodelElementProvider.PROPERTIES + "/cfgProperty2");
+		assertEquals("12", value2.get(Property.VALUE));
+		// - Check property meta data (description)
+		Map<String, Object> value2a = (Map<String, Object>) connSubModel
+				.getModelPropertyValue("/aas/submodels/sampleCFG/" + SubmodelElementProvider.PROPERTIES + "/cfgProperty2");
+		description = LangStrings.createAsFacade((Collection<Map<String, Object>>) value2a.get("description"));
+		assertEquals("Configuration property description on multiple lines", description.get(""));
+
+		// Get property value
+		Map<String, Object> value3 = (Map<String, Object>) connSubModel
+				.getModelPropertyValue("/aas/submodels/sampleCFG/" + SubmodelElementProvider.PROPERTIES + "/cfgProperty3");
+		assertEquals("45.8", value3.get(Property.VALUE));
+	}
+}
diff --git a/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/cfgprovider/TestCFGProviderSubmodelMetaData.java b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/cfgprovider/TestCFGProviderSubmodelMetaData.java
new file mode 100644
index 0000000..a3dfb92
--- /dev/null
+++ b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/cfgprovider/TestCFGProviderSubmodelMetaData.java
@@ -0,0 +1,68 @@
+package org.eclipse.basyx.sandbox.regression.components.cfgprovider;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Collection;
+import java.util.Map;
+
+import org.eclipse.basyx.regression.support.directory.ComponentsTestsuiteDirectory;
+import org.eclipse.basyx.regression.support.server.context.ComponentsRegressionContext;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.AdministrativeInformation;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Identifiable;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangStrings;
+import org.eclipse.basyx.testsuite.regression.vab.protocol.http.AASHTTPServerResource;
+import org.eclipse.basyx.vab.manager.VABConnectionManager;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
+import org.junit.ClassRule;
+import org.junit.Test;
+
+
+
+/**
+ * Test queries to CFG file provider
+ * 
+ * @author kuhn
+ *
+ */
+public class TestCFGProviderSubmodelMetaData {
+
+	
+	/**
+	 * VAB connection manager backend
+	 */
+	protected VABConnectionManager connManager = new VABConnectionManager(new ComponentsTestsuiteDirectory(), new HTTPConnectorProvider());
+
+	/** 
+	 * Makes sure Tomcat Server is started
+	 */
+	@ClassRule
+	public static AASHTTPServerResource res = new AASHTTPServerResource(new ComponentsRegressionContext());
+	
+	/**
+	 * Test basic queries
+	 */
+	@SuppressWarnings("unchecked")
+	@Test
+	public void test() throws Exception {
+
+		// Connect to sub model "CfgFileTestAAS"
+		VABElementProxy connSubModel = this.connManager.connectToVABElement("CfgFileTestAAS");
+
+		
+		// Get property value
+		Map<String, Object> sampleCFG = (Map<String, Object>) connSubModel
+				.getModelPropertyValue("/aas/submodels/sampleCFG");
+		
+		LangStrings description = LangStrings.createAsFacade((Collection<Map<String, Object>>) sampleCFG.get("description"));
+		assertEquals("BaSys regression test file for CFG file provider", description.get(""));
+
+		// Get property value
+		assertEquals("1.0",
+				AdministrativeInformation.createAsFacade((Map<String, Object>) sampleCFG.get(Identifiable.ADMINISTRATION))
+				.getVersion());
+
+		// Get complete sub model
+		Object value3 = connSubModel.getModelPropertyValue("/aas/submodels/sampleCFG");
+	}
+}
diff --git a/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/directory/file/TestAASDirectoryEntry.java b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/directory/file/TestAASDirectoryEntry.java
new file mode 100644
index 0000000..7ad49ce
--- /dev/null
+++ b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/directory/file/TestAASDirectoryEntry.java
@@ -0,0 +1,217 @@
+package org.eclipse.basyx.sandbox.regression.components.directory.file;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.eclipse.basyx.sandbox.components.registry.AASDirectoryEntry;
+import org.junit.Test;
+
+
+
+/**
+ * Test the AAS Directory entry class
+ * 
+ * @author kuhn
+ *
+ */
+public class TestAASDirectoryEntry {
+
+	
+	
+	/**
+	 * Execute test case that tests parsing of id constructor parameter
+	 */
+	@Test
+	public void testConstuctorParameterID() {
+		// Test object with minimal ID
+		AASDirectoryEntry aasEntry1 = new AASDirectoryEntry("urn:FHG", "<serializedAAS>", "local", "");
+		// - Validate object
+		assertTrue(aasEntry1.isValidID());
+		assertTrue(aasEntry1.getLegalEntity().equals("FHG"));
+		assertTrue(aasEntry1.isLegalEntityOf("FHG"));
+		assertFalse(aasEntry1.hasSubUnit());
+		assertFalse(aasEntry1.hasSubModel());
+		assertFalse(aasEntry1.hasVersion());
+		assertFalse(aasEntry1.hasRevision());
+		
+		
+		// Test object with empty ID, SubUnit and sub model
+		AASDirectoryEntry aasEntry2 = new AASDirectoryEntry("urn:::::", "<serializedAAS>", "local", "");
+		// - Validate object
+		assertTrue(aasEntry2.isValidID());
+		assertFalse(aasEntry2.hasLegalEntity());
+		assertFalse(aasEntry2.hasSubUnit());
+		assertFalse(aasEntry2.hasSubModel());
+		assertFalse(aasEntry2.hasVersion());
+		assertFalse(aasEntry2.hasRevision());
+
+		
+		// Test object with almost empty ID and SubUnit
+		AASDirectoryEntry aasEntry3 = new AASDirectoryEntry("urn: : : : : ", "<serializedAAS>", "local", "");
+		// - Validate object
+		assertTrue(aasEntry3.isValidID());
+		assertFalse(aasEntry3.hasLegalEntity());
+		assertFalse(aasEntry3.hasSubUnit());
+		assertFalse(aasEntry3.hasSubModel());
+		assertFalse(aasEntry3.hasVersion());
+		assertFalse(aasEntry3.hasRevision());
+
+		
+		// Test object with ID, SubUnit, version and revision
+		AASDirectoryEntry aasEntry4 = new AASDirectoryEntry("urn:FHG:iese:aas:0.97:1", "<serializedAAS>", "local", "");
+		// - Validate object
+		assertTrue(aasEntry4.isValidID());
+		assertTrue(aasEntry4.getLegalEntity().equals("FHG"));
+		assertTrue(aasEntry4.isLegalEntityOf("FHG"));
+		assertTrue(aasEntry4.hasSubUnit());
+		assertTrue(aasEntry4.getSubUnit().equals("iese"));
+		assertTrue(aasEntry4.hasSubModel());
+		assertTrue(aasEntry4.getSubModel().equals("aas"));
+		assertTrue(aasEntry4.hasVersion());
+		assertTrue(aasEntry4.getVersion().equals("0.97"));
+		assertTrue(aasEntry4.hasRevision());
+		assertTrue(aasEntry4.getRevision().equals("1"));
+		assertFalse(aasEntry4.hasElementID());
+
+		
+		// Test object with ID, SubUnit, version and revision
+		AASDirectoryEntry aasEntry5 = new AASDirectoryEntry("urn:FHG:iese:aas:0.97:1:entity", "<serializedAAS>", "local", "");
+		// - Validate object
+		assertTrue(aasEntry5.isValidID());
+		assertTrue(aasEntry5.getLegalEntity().equals("FHG"));
+		assertTrue(aasEntry5.isLegalEntityOf("FHG"));
+		assertTrue(aasEntry5.hasSubUnit());
+		assertTrue(aasEntry5.getSubUnit().equals("iese"));
+		assertTrue(aasEntry5.hasSubModel());
+		assertTrue(aasEntry5.getSubModel().equals("aas"));
+		assertTrue(aasEntry5.hasVersion());
+		assertTrue(aasEntry5.getVersion().equals("0.97"));
+		assertTrue(aasEntry5.hasRevision());
+		assertTrue(aasEntry5.getRevision().equals("1"));
+		assertTrue(aasEntry5.hasElementID());
+		assertTrue(aasEntry5.getElementID().equals("entity"));
+
+		
+		// Test object with ID, SubUnit, version and revision
+		AASDirectoryEntry aasEntry6 = new AASDirectoryEntry("urn:FHG:iese:aas:0.97:1:entity#001", "<serializedAAS>", "local", "");
+		// - Validate object
+		assertTrue(aasEntry6.isValidID());
+		assertTrue(aasEntry6.getLegalEntity().equals("FHG"));
+		assertTrue(aasEntry6.isLegalEntityOf("FHG"));
+		assertTrue(aasEntry6.hasSubUnit());
+		assertTrue(aasEntry6.getSubUnit().equals("iese"));
+		assertTrue(aasEntry6.hasSubModel());
+		assertTrue(aasEntry6.getSubModel().equals("aas"));
+		assertTrue(aasEntry6.hasVersion());
+		assertTrue(aasEntry6.getVersion().equals("0.97"));
+		assertTrue(aasEntry6.hasRevision());
+		assertTrue(aasEntry6.getRevision().equals("1"));
+		assertTrue(aasEntry6.hasElementID());
+		assertTrue(aasEntry6.getElementID().equals("entity"));
+		assertTrue(aasEntry6.hasElementInstance());
+		assertTrue(aasEntry6.getElementInstance().equals("001"));
+
+		
+		// Test object with ID, SubUnit, version and revision
+		AASDirectoryEntry aasEntry7 = new AASDirectoryEntry("urn:FHG:iese:aas:0.97:1:#001", "<serializedAAS>", "local", "");
+		// - Validate object
+		assertTrue(aasEntry7.isValidID());
+		assertTrue(aasEntry7.getLegalEntity().equals("FHG"));
+		assertTrue(aasEntry7.isLegalEntityOf("FHG"));
+		assertTrue(aasEntry7.hasSubUnit());
+		assertTrue(aasEntry7.getSubUnit().equals("iese"));
+		assertTrue(aasEntry7.hasSubModel());
+		assertTrue(aasEntry7.getSubModel().equals("aas"));
+		assertTrue(aasEntry7.hasVersion());
+		assertTrue(aasEntry7.getVersion().equals("0.97"));
+		assertTrue(aasEntry7.hasRevision());
+		assertTrue(aasEntry7.getRevision().equals("1"));
+		assertFalse(aasEntry7.hasElementID());
+		assertTrue(aasEntry7.hasElementInstance());
+		assertTrue(aasEntry7.getElementInstance().equals("001"));
+	}
+
+	
+	
+	/**
+	 * Execute test case that tests parsing of content and content type constructor parameter
+	 */
+	@Test
+	public void testConstuctorParameterContentAndContentType() {
+		// Test object with local content and without tags
+		AASDirectoryEntry aasEntry1 = new AASDirectoryEntry("urn:FHG:iese:aas:0.97:1:#001", "<serializedAAS>", "local", "");
+		// - Validate object
+		assertTrue(aasEntry1.getAASContent().equals("<serializedAAS>"));
+		assertTrue(aasEntry1.getAASContentType() == AASDirectoryEntry.AAS_CONTENTTYPE_LOCAL);
+		assertTrue(aasEntry1.getAASTags().isEmpty());
+		
+		
+		// Test object with remote content and without tags
+		AASDirectoryEntry aasEntry2 = new AASDirectoryEntry("urn:FHG:iese:aas:0.97:1:#001", "<serializedAAS>", "remote", "");
+		// - Validate object
+		assertTrue(aasEntry2.getAASContent().equals("<serializedAAS>"));
+		assertTrue(aasEntry2.getAASContentType() == AASDirectoryEntry.AAS_CONTENTTYPE_REMOTE);
+		assertTrue(aasEntry2.getAASTags().isEmpty());
+
+		
+		// Test object with remote content and without tags
+		AASDirectoryEntry aasEntry3 = new AASDirectoryEntry("urn:FHG:iese:aas:0.97:1:#001", "<serializedAAS>", "ReMote", "");
+		// - Validate object
+		assertTrue(aasEntry3.getAASContent().equals("<serializedAAS>"));
+		assertTrue(aasEntry3.getAASContentType() == AASDirectoryEntry.AAS_CONTENTTYPE_REMOTE);
+		assertTrue(aasEntry3.getAASTags().isEmpty());
+
+		
+		// Test object with proxy content and without tags
+		AASDirectoryEntry aasEntry4 = new AASDirectoryEntry("urn:FHG:iese:aas:0.97:1:#001", "<serializedAAS>", "PROXY", "");
+		// - Validate object
+		assertTrue(aasEntry4.getAASContent().equals("<serializedAAS>"));
+		assertTrue(aasEntry4.getAASContentType() == AASDirectoryEntry.AAS_CONTENTTYPE_PROXY);
+		assertTrue(aasEntry4.getAASTags().isEmpty());
+	}
+
+	
+	
+	/**
+	 * Execute test case that tests parsing of tags constructor parameter
+	 */
+	@Test
+	public void testConstuctorParameterTags() {
+		// Test object without tags
+		AASDirectoryEntry aasEntry1 = new AASDirectoryEntry("urn:FHG:iese:aas:0.97:1:#001", "<serializedAAS>", "local", "");
+		// - Validate object
+		assertTrue(aasEntry1.getAASTags().isEmpty());
+		
+		
+		// Test object with one tag
+		AASDirectoryEntry aasEntry2 = new AASDirectoryEntry("urn:FHG:iese:aas:0.97:1:#001", "<serializedAAS>", "local", "tag1");
+		// - Validate object
+		assertTrue(aasEntry2.getAASTags().size() == 1);
+		assertTrue(aasEntry2.getAASTags().toArray(new String[1])[0].equals("tag1"));
+
+		
+		// Test object with one tag
+		AASDirectoryEntry aasEntry3 = new AASDirectoryEntry("urn:FHG:iese:aas:0.97:1:#001", "<serializedAAS>", "local", "tag1,tag2");
+		// - Validate object
+		assertTrue(aasEntry3.getAASTags().size() == 2);
+		assertTrue(aasEntry3.getAASTags().toArray(new String[2])[0].equals("tag1"));
+		assertTrue(aasEntry3.getAASTags().toArray(new String[2])[1].equals("tag2"));
+	}
+
+	
+	
+	/**
+	 * Execute test case that tests invalid directory entries
+	 */
+	@Test
+	public void testInvalidConstuctorParameter() {
+		// Test object with minimal ID
+		AASDirectoryEntry aasEntry1 = new AASDirectoryEntry("FHG", "<serializedAAS>", "local", "");
+		// - Validate object
+		assertFalse(aasEntry1.isValidID());
+		assertFalse(aasEntry1.hasLegalEntity());
+		assertFalse(aasEntry1.hasSubUnit());
+		assertFalse(aasEntry1.hasSubModel());
+	}
+}
+
diff --git a/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/directory/file/TestStaticDirectoryFileProvider.java b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/directory/file/TestStaticDirectoryFileProvider.java
new file mode 100644
index 0000000..0395d56
--- /dev/null
+++ b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/directory/file/TestStaticDirectoryFileProvider.java
@@ -0,0 +1,142 @@
+package org.eclipse.basyx.sandbox.regression.components.directory.file;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+
+import org.eclipse.basyx.regression.support.server.context.ComponentsRegressionContext;
+import org.eclipse.basyx.testsuite.regression.vab.protocol.http.AASHTTPServerResource;
+import org.eclipse.basyx.tools.webserviceclient.WebServiceRawClient;
+import org.eclipse.basyx.vab.coder.json.metaprotocol.MetaprotocolHandler;
+import org.junit.ClassRule;
+import org.junit.Test;
+
+
+
+
+/**
+ * Test queries to CFG file directory provider
+ * 
+ * @author kuhn
+ *
+ */
+public class TestStaticDirectoryFileProvider {
+
+	/** 
+	 * Makes sure Tomcat Server is started
+	 */
+	@ClassRule
+	public static AASHTTPServerResource res = new AASHTTPServerResource(new ComponentsRegressionContext());
+	private MetaprotocolHandler handler = new MetaprotocolHandler();
+
+	/**
+	 * Execute test case that test working calls
+	 */
+	@Test
+	public void testWorkingCalls() {
+		// Invoke BaSyx service calls via web services
+		WebServiceRawClient client = new WebServiceRawClient();
+		
+		// Directory web service URL
+		String wsURL = "http://localhost:8080/basys.components/Testsuite/Directory/CFGFile";
+		
+		
+		// First test - get all locally registered AAS
+		{
+			// Get all locally registered AAS
+			String result = getResult(client.get(wsURL + "/api/v1/registry"));
+
+			// Check if all AAS are contained in result
+			assertTrue(result.contains("{content.aas1}"));
+			assertTrue(result.contains("{content.aas2}"));
+			assertTrue(result.contains("{content.aas3}"));
+			assertTrue(result.contains("{content.aas4}"));
+		}
+		
+		
+		// Get a specific AAS (1)
+		try {
+			// Get a known AAS by its ID
+			String result = getResult(client.get(wsURL + "/api/v1/registry/urn:de.FHG:es.iese:aas:0.98:5:lab/" + URLEncoder.encode("microscope#A-19", "UTF-8")));
+
+			// Check if all AAS are contained in result
+			assertTrue(result.equals("{content.aas1}"));
+		} catch (Exception e) {
+			fail("Get specific AAS test case did throw exception:"+e);
+		}
+
+		
+		// Get a specific AAS (2)
+		try {
+			// Get a known AAS by its ID
+			String result = getResult(client.get(wsURL + "/api/v1/registry/urn:de.FHG:es.iese:aas:0.98:5:lab/" + URLEncoder.encode("microscope#A-18", "UTF-8")));
+
+			// Check if all AAS are contained in result
+			assertTrue(result.equals("{content.aas2}"));
+		} catch (Exception e) {
+			fail("Get specific AAS test case did throw exception:"+e);
+		}
+
+		
+		// Get a specific AAS (3)
+		try {
+			// Get a known AAS by its ID
+			String result = getResult(client.get(wsURL + "/api/v1/registry/urn:de.FHG:es.iese:aas:0.98:5:lab/" + URLEncoder.encode("microscope#A-17", "UTF-8")));
+
+			// Check if all AAS are contained in result
+			assertTrue(result.equals("{content.aas3}"));
+		} catch (Exception e) {
+			fail("Get specific AAS test case did throw exception:"+e);
+		}
+
+		
+		// Get a specific AAS (4)
+		try {
+			// Get a known AAS by its ID
+			String result = getResult(client.get(wsURL + "/api/v1/registry/urn:de.FHG:es.iese:aas:0.98:5:lab/" + URLEncoder.encode("microscope#A-16", "UTF-8")));
+
+			// Check if all AAS are contained in result
+			assertTrue(result.equals("{content.aas4}"));
+		} catch (Exception e) {
+			fail("Get specific AAS test case did throw exception:"+e);
+		}
+	}
+	
+	
+	
+	/**
+	 * Execute test case that test non-working calls
+	 * 
+	 * @throws UnsupportedEncodingException
+	 */
+	@Test
+	public void testNonWorkingCalls() throws UnsupportedEncodingException {
+		// Invoke service call via web services
+		WebServiceRawClient client = new WebServiceRawClient();
+		
+		// Directory web service URL
+		String wsURL = "http://localhost:8080/basys.components/Testsuite/Directory/CFGFile";
+
+		
+		// Get unknown AAS ID
+		// Get a known AAS by its ID
+		String result = getResult(client.get(
+				wsURL + "/api/v1/registry/urn:de.FHG:es.iese:aas:0.98:5:lab/" + URLEncoder.encode("unknown", "UTF-8")));
+
+		// Check if the getting a non existing URL returns a null
+		assertEquals(null, result);
+	}
+
+	private String getResult(String res) {
+		try {
+			return (String) handler.deserialize(res);
+		} catch (Exception e) {
+			throw new RuntimeException(e);
+		}
+	}
+}
+
+
diff --git a/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/directory/file/TestStaticDirectoryFileProviderExceptions.java b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/directory/file/TestStaticDirectoryFileProviderExceptions.java
new file mode 100644
index 0000000..369c60d
--- /dev/null
+++ b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/directory/file/TestStaticDirectoryFileProviderExceptions.java
@@ -0,0 +1,91 @@
+package org.eclipse.basyx.sandbox.regression.components.directory.file;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+
+import javax.ws.rs.ServerErrorException;
+
+import org.eclipse.basyx.regression.support.server.context.ComponentsRegressionContext;
+import org.eclipse.basyx.testsuite.regression.vab.protocol.http.AASHTTPServerResource;
+import org.eclipse.basyx.tools.webserviceclient.WebServiceJSONClient;
+import org.junit.ClassRule;
+import org.junit.Test;
+
+
+
+/**
+ * Test queries to CFG file provider
+ * 
+ * @author kuhn
+ *
+ */
+public class TestStaticDirectoryFileProviderExceptions {
+
+	/** 
+	 * Makes sure Tomcat Server is started
+	 */
+	@ClassRule
+	public static AASHTTPServerResource res = new AASHTTPServerResource(new ComponentsRegressionContext());
+	
+	/**
+	 * Execute test case that tests not implemented calls
+	 * 
+	 * @throws UnsupportedEncodingException
+	 */
+	@Test
+	public void testUnsupportedCalls() throws UnsupportedEncodingException {
+		// Invoke BaSyx service calls via web services
+		WebServiceJSONClient client = new WebServiceJSONClient();
+		
+		// Directory web service URL
+		String wsURL = "http://localhost:8080/basys.components/Testsuite/Directory/CFGFile";
+		
+
+		
+		// Register a new AAS (using POST)
+		try {
+			// Get a known AAS by its ID
+			client.post(wsURL + "/api/v1/registry", "Some content");
+
+			// Exception was not thrown
+			fail("Expected exception indicating that feature is not implemented was not thrown");
+		} catch (ServerErrorException e) {
+			// Check return code for expected return value (501)
+			assertEquals(501, e.getResponse().getStatus());
+			
+		}
+
+		
+		
+		// Renew a specific AAS registration (using PUT)
+		try {
+			// Get a known AAS by its ID
+			client.put(wsURL + "/api/v1/registry/urn:de.FHG:es.iese:aas:0.98:5:lab/" + URLEncoder.encode("microscope#A-19", "UTF-8"), "Some updated content");
+
+			// Exception was not thrown
+			fail("Expected exception indicating that feature is not implemented was not thrown");
+		} catch (ServerErrorException e) {
+			// Check return code for expected return value (501)
+			assertEquals(501, e.getResponse().getStatus());
+		}
+
+		
+		// Delete a specific AAS registration (using PUT)
+		try {
+			// Get a known AAS by its ID
+			client.delete(wsURL+"/api/v1/registry/urn:de.FHG:es.iese:aas:0.98:5:lab/"+URLEncoder.encode("microscope#A-19","UTF-8"));
+
+			// Exception was not thrown
+			fail("Expected exception indicating that feature is not implemented was not thrown");
+		} catch (ServerErrorException e) {
+			// Check return code for expected return value (501)
+			assertEquals(501, e.getResponse().getStatus());
+		}
+
+	}
+}
+
+
diff --git a/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/rawcfgprovider/TestRawCFGProviderAAS.java b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/rawcfgprovider/TestRawCFGProviderAAS.java
new file mode 100644
index 0000000..c113a3f
--- /dev/null
+++ b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/rawcfgprovider/TestRawCFGProviderAAS.java
@@ -0,0 +1,71 @@
+package org.eclipse.basyx.sandbox.regression.components.rawcfgprovider;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+import org.eclipse.basyx.regression.support.directory.ComponentsTestsuiteDirectory;
+import org.eclipse.basyx.regression.support.server.context.ComponentsRegressionContext;
+import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.testsuite.regression.vab.protocol.http.AASHTTPServerResource;
+import org.eclipse.basyx.vab.manager.VABConnectionManager;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
+import org.junit.ClassRule;
+import org.junit.Test;
+
+
+
+/**
+ * Test queries to CFG file provider
+ * 
+ * @author kuhn
+ *
+ */
+public class TestRawCFGProviderAAS {
+
+	
+	/**
+	 * VAB connection manager backend
+	 */
+	protected VABConnectionManager connManager = new VABConnectionManager(new ComponentsTestsuiteDirectory(), new HTTPConnectorProvider());
+
+	/** 
+	 * Makes sure Tomcat Server is started
+	 */
+	@ClassRule
+	public static AASHTTPServerResource res = new AASHTTPServerResource(new ComponentsRegressionContext());
+	
+	/**
+	 * Test basic queries
+	 */
+	@SuppressWarnings({ "unchecked" })
+	@Test
+	public void test() throws Exception {
+
+		// Connect to sub model "CfgFileTestAAS"
+		VABElementProxy connSubModel = this.connManager.connectToVABElement("AASProvider");
+
+		
+		// Create map with complex type
+		AssetAdministrationShell aas = new AssetAdministrationShell();
+		aas.setIdShort("testAAS");
+		
+		// Create AAS structure on server
+		connSubModel.createValue("/aas", aas);
+
+		
+		// Read complex property completely
+		Map<String, Object> aasReadBack = (Map<String, Object>) connSubModel.getModelPropertyValue("/aas");
+
+		assertEquals(aas.getIdShort(), AssetAdministrationShell.createAsFacade(aasReadBack).getIdShort());
+		
+		// Read AAS SubModel
+		Map<String, Object> smReadBack = (Map<String, Object>) connSubModel
+				.getModelPropertyValue("/aas/submodels/rawSampleCFG");
+		
+		assertEquals("rawSampleCFG", SubModel.createAsFacade(smReadBack).getIdShort());
+		
+	}
+}
diff --git a/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/rawcfgprovider/TestRawCFGProviderAASNewModel.java b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/rawcfgprovider/TestRawCFGProviderAASNewModel.java
new file mode 100644
index 0000000..784ed50
--- /dev/null
+++ b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/rawcfgprovider/TestRawCFGProviderAASNewModel.java
@@ -0,0 +1,62 @@
+package org.eclipse.basyx.sandbox.regression.components.rawcfgprovider;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Map;
+
+import org.eclipse.basyx.regression.support.directory.ComponentsTestsuiteDirectory;
+import org.eclipse.basyx.regression.support.server.context.ComponentsRegressionContext;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
+import org.eclipse.basyx.testsuite.regression.vab.protocol.http.AASHTTPServerResource;
+import org.eclipse.basyx.vab.manager.VABConnectionManager;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
+import org.junit.ClassRule;
+import org.junit.Test;
+
+
+
+/**
+ * Test queries to CFG file provider
+ * 
+ * @author kuhn
+ *
+ */
+public class TestRawCFGProviderAASNewModel {
+
+	
+	/**
+	 * VAB connection manager backend
+	 */
+	protected VABConnectionManager connManager = new VABConnectionManager(new ComponentsTestsuiteDirectory(), new HTTPConnectorProvider());
+
+	/** 
+	 * Makes sure Tomcat Server is started
+	 */
+	@ClassRule
+	public static AASHTTPServerResource res = new AASHTTPServerResource(new ComponentsRegressionContext());
+	
+	/**
+	 * Test basic queries
+	 */
+	@SuppressWarnings({ "unchecked", "unused" })
+	@Test
+	public void test() throws Exception {
+
+		// Connect to sub model "CfgFileTestAAS"
+		VABElementProxy connSubModel = this.connManager.connectToVABElement("RawCfgFileTestAAS");
+
+		
+		// Create map with complex type
+		Property prop = new Property ();
+		prop.setIdShort("prop");
+		// Create AAS structure on server
+		connSubModel.createValue("/aas/submodels/rawSampleCFG/" + SubmodelElementProvider.PROPERTIES, prop);
+
+		
+		// Read complex property completely
+		Map<String, Object> aasReadBack = (Map<String, Object>) connSubModel.getModelPropertyValue("/aas/submodels/rawSampleCFG/" + SubmodelElementProvider.PROPERTIES + "/prop");
+		assertEquals(prop.getIdShort(), Property.createAsFacade(prop).getIdShort());
+	}
+}
diff --git a/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/rawcfgprovider/TestRawCFGProviderSimpleValues.java b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/rawcfgprovider/TestRawCFGProviderSimpleValues.java
new file mode 100644
index 0000000..4863157
--- /dev/null
+++ b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/rawcfgprovider/TestRawCFGProviderSimpleValues.java
@@ -0,0 +1,88 @@
+package org.eclipse.basyx.sandbox.regression.components.rawcfgprovider;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Map;
+
+import org.eclipse.basyx.regression.support.directory.ComponentsTestsuiteDirectory;
+import org.eclipse.basyx.regression.support.server.context.ComponentsRegressionContext;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.AdministrativeInformation;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Identifiable;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
+import org.eclipse.basyx.testsuite.regression.vab.protocol.http.AASHTTPServerResource;
+import org.eclipse.basyx.vab.manager.VABConnectionManager;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
+import org.junit.ClassRule;
+import org.junit.Test;
+
+/**
+ * Test queries to CFG file provider
+ * 
+ * @author kuhn
+ *
+ */
+public class TestRawCFGProviderSimpleValues {
+
+	/**
+	 * VAB connection manager backend
+	 */
+	protected VABConnectionManager connManager = new VABConnectionManager(new ComponentsTestsuiteDirectory(),
+			new HTTPConnectorProvider());
+
+	/**
+	 * Makes sure Tomcat Server is started
+	 */
+	@ClassRule
+	public static AASHTTPServerResource res = new AASHTTPServerResource(new ComponentsRegressionContext());
+
+	/**
+	 * Test basic queries
+	 */
+	@SuppressWarnings("unchecked")
+	@Test
+	public void test() throws Exception {
+
+		// Connect to sub model "CfgFileTestAAS"
+		VABElementProxy connSubModel = this.connManager.connectToVABElement("RawCfgFileTestAAS");
+
+		// Check sub model meta data
+		Map<String, Object> submodel = (Map<String, Object>) connSubModel
+				.getModelPropertyValue("/aas/submodels/rawSampleCFG");
+		assertEquals("1.0",
+				AdministrativeInformation.createAsFacade((Map<String, Object>) submodel.get(Identifiable.ADMINISTRATION))
+						.getVersion());
+
+		// Get property value
+		Map<String, Object> value1 = (Map<String, Object>) connSubModel
+				.getModelPropertyValue("/aas/submodels/rawSampleCFG/" + SubmodelElementProvider.PROPERTIES + "/cfgProperty1/value");
+		assertEquals("exampleStringValueRaw", value1.get(Property.VALUE));
+		Map<String, Object> cfgProperty1 = (Map<String, Object>) connSubModel
+				.getModelPropertyValue("/aas/submodels/rawSampleCFG/" + SubmodelElementProvider.PROPERTIES + "/cfgProperty1");
+		assertEquals("Configuration property description", cfgProperty1.get("description"));
+
+		// Get property value
+		Map<String, Object> value2 = (Map<String, Object>) connSubModel
+				.getModelPropertyValue("/aas/submodels/rawSampleCFG/" + SubmodelElementProvider.PROPERTIES + "/cfgProperty2/value");
+		assertEquals(12, value2.get(Property.VALUE));
+		// - Check property meta data (description)
+		Map<String, Object> cfgProperty2 = (Map<String, Object>) connSubModel
+				.getModelPropertyValue("/aas/submodels/rawSampleCFG/" + SubmodelElementProvider.PROPERTIES + "/cfgProperty2");
+		assertEquals("Configuration property description on multiple lines", cfgProperty2.get("description"));
+
+		// Get property value
+		Map<String, Object> value3 = (Map<String, Object>) connSubModel
+				.getModelPropertyValue("/aas/submodels/rawSampleCFG/" + SubmodelElementProvider.PROPERTIES + "/cfgProperty3/value");
+		assertEquals("45.8", value3.get(Property.VALUE));
+
+		// Get property value
+		Map<String, Object> value4 = (Map<String, Object>) connSubModel
+				.getModelPropertyValue("/aas/submodels/rawSampleCFG/" + SubmodelElementProvider.PROPERTIES + "/cfgProperty4/value");
+		assertEquals("44.8", value4.get(Property.VALUE));
+		Map<String, Object> cfgProperty4 = (Map<String, Object>) connSubModel
+				.getModelPropertyValue("/aas/submodels/rawSampleCFG/" + SubmodelElementProvider.PROPERTIES + "/cfgProperty4");
+		assertEquals("Another configuration property description", cfgProperty4.get("description"));
+		assertEquals("8", cfgProperty4.get("newMetaData"));
+	}
+}
diff --git a/sdks/c++/basys.sdk.cc/.gitignore b/sdks/c++/basys.sdk.cc/.gitignore
index 24c9089..b0357a0 100644
--- a/sdks/c++/basys.sdk.cc/.gitignore
+++ b/sdks/c++/basys.sdk.cc/.gitignore
@@ -4,5 +4,6 @@
 .cproject
 bin/
 compile_commands.json
-.clangd
-run-msbuild.bat
\ No newline at end of file
+run-msbuild.bat
+.clangd/
+*.swp
diff --git a/sdks/c++/basys.sdk.cc/CMakeLists.txt b/sdks/c++/basys.sdk.cc/CMakeLists.txt
index c79f618..ec9b6d6 100644
--- a/sdks/c++/basys.sdk.cc/CMakeLists.txt
+++ b/sdks/c++/basys.sdk.cc/CMakeLists.txt
@@ -13,6 +13,9 @@
 include(enable_testbed)
 include(GNUInstallDirs)
 
+# Check if standalone build or being included as submodule
+get_directory_property(BASYX_IS_SUBMODULE PARENT_DIRECTORY)
+
 set (BASYX_PACKAGE_VERSION_MAJOR "0")
 set (BASYX_PACKAGE_VERSION_MINOR "1")
 set (BASYX_PACKAGE_VERSION_PATCH "0")
@@ -34,24 +37,43 @@
 message(STATUS "CMAKE_BINARY_DIR: ${CMAKE_BINARY_DIR}")
 message(STATUS "" )
 
+if(NOT BASYX_IS_SUBMODULE)
 set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
 set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
 set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
+endif()
 
 ### BaSyx directories ###
-set(BASYX_SOURCE_DIR  "${CMAKE_SOURCE_DIR}/src")
-set(BASYX_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/include")
-set(BASYX_TEST_DIR    "${CMAKE_SOURCE_DIR}/regression")
-set(BASYX_LIBRARY_DIR "${CMAKE_SOURCE_DIR}/lib")
+set(BASYX_SOURCE_DIR  "${CMAKE_CURRENT_SOURCE_DIR}/src")
+set(BASYX_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/include")
+set(BASYX_TEST_DIR    "${CMAKE_CURRENT_SOURCE_DIR}/regression")
+set(BASYX_LIBRARY_DIR "${CMAKE_CURRENT_SOURCE_DIR}/lib")
+
+## Set project defaults
+if(BASYX_IS_SUBMODULE)
+  message(STATUS "BaSyx included as submodule.")
+  set(BASYX_BUILD_TESTS_DEFAULT OFF)
+  set(BASYX_UTILITY_PROJECTS_DEFAULT OFF)
+  set(BASYX_INSTALL_SDK_DEFAULT OFF)
+  set(BUILD_SHARED_LIBS_DEFAULT OFF)
+  set(BASYX_VERBOSE_CMAKE_OUTPUT OFF)
+else()
+  set(BASYX_BUILD_TESTS_DEFAULT ON)
+  set(BASYX_UTILITY_PROJECTS_DEFAULT ON)
+  set(BASYX_INSTALL_SDK_DEFAULT ON)
+  set(BUILD_SHARED_LIBS_DEFAULT OFF)
+endif()
 
 ### Build options ###
-set(BASYX_BUILD_TESTS ON CACHE BOOL "Build unit tests")
+set(BASYX_BUILD_TESTS ${BASYX_BUILD_TESTS_DEFAULT} CACHE BOOL "Build unit tests")
 set(BASYX_BUILD_API ON CACHE BOOL "Build BaSyx API")
-set(BASYX_UTILITY_PROJECTS ON CACHE BOOL "Create utility targets")
+set(BASYX_UTILITY_PROJECTS ${BASYX_UTILITY_PROJECTS_DEFAULT} CACHE BOOL "Create utility targets")
 set(BASYX_DEBUG_PRINT_FRAMES OFF CACHE BOOL "Print BaSyx frames")
-set(BASYX_INSTALL_SDK ON CACHE BOOL "Create install instructions for BaSyx SDK")
+set(BASYX_INSTALL_SDK ${BASYX_INSTALL_SDK_DEFAULT} CACHE BOOL "Create install instructions for BaSyx SDK")
+option(BASYX_VERBOSE_CMAKE_OUTPUT "Show detailed CMake output" ON)
 
-set(BUILD_SHARED_LIBS OFF CACHE BOOL "Build Shared (.so / .dll) instead of static libraries")
+
+set(BUILD_SHARED_LIBS ${BUILD_SHARED_LIBS_DEFAULT} CACHE BOOL "Build Shared (.so / .dll) instead of static libraries")
 
 option(BASYX_USE_SYSTEM_LIBFMT "Wether to build external, yet included library libfmt" OFF)
 option(BASYX_USE_SYSTEM_ASIO "Use system supplied ASIO library." OFF)
@@ -64,8 +86,12 @@
 add_compile_definitions(BASYX_MAJOR_REV=${BASYX_PACKAGE_VERSION_MAJOR})
 add_compile_definitions(BASYX_MINOR_REV=${BASYX_PACKAGE_VERSION_MINOR})
 add_compile_definitions(BASYX_PATCH_REV=${BASYX_PACKAGE_VERSION_PATCH})
-add_compile_definitions(WIN32_LEAN_AND_MEAN)
-##add_compile_definitions(__USE_MINGW_ANSI_STDIO=0)
+
+### Load system specific config ###
+if(WIN32)
+	include(config.windows)
+endif()
+
 
 ###############################################
 ###           Library Settings              ###
@@ -106,7 +132,7 @@
 ###############################################
 ###           Source Directory              ###
 ###############################################
-include_directories("${BASYX_INCLUDE_DIR}")
+#include_directories("${BASYX_INCLUDE_DIR}")
 
 add_subdirectory(src/abstraction)
 add_subdirectory(src/logging)
@@ -115,7 +141,7 @@
 add_subdirectory(src/vab)
 add_subdirectory(src/server)
 add_subdirectory(src/submodel)
-add_subdirectory(src/aas)
+add_subdirectory(src/controlcomponent)
 
 ###############################################
 ###           Test Directory                ###
@@ -147,7 +173,7 @@
 # Let the projects using our server infrastucure find asio (interally /
 # externally provided)
 
-install(FILES ${CMAKE_CURRENT_BINARY_DIR}/cmake/Findasio.cmake
+install(FILES ${CMAKE_SOURCE_DIR}/cmake/Findasio.cmake
 		DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/BaSyxAsio
 )
 
@@ -188,4 +214,4 @@
 BaSyx, please use distribution provided libraries if possible!")
 endif()
 	
-endif() # ${BASYX_INSTALL_SDK}
\ No newline at end of file
+endif() # ${BASYX_INSTALL_SDK}
diff --git a/sdks/c++/basys.sdk.cc/cmake/config.windows.cmake b/sdks/c++/basys.sdk.cc/cmake/config.windows.cmake
new file mode 100644
index 0000000..9c599cc
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/cmake/config.windows.cmake
@@ -0,0 +1,3 @@
+add_compile_definitions(WIN32_LEAN_AND_MEAN)
+add_compile_definitions(_CRT_SECURE_NO_WARNINGS)
+add_compile_options(/wd4250)
diff --git a/sdks/c++/basys.sdk.cc/cmake/diagnostics_print.cmake b/sdks/c++/basys.sdk.cc/cmake/diagnostics_print.cmake
index e5e807e..a07ec14 100644
--- a/sdks/c++/basys.sdk.cc/cmake/diagnostics_print.cmake
+++ b/sdks/c++/basys.sdk.cc/cmake/diagnostics_print.cmake
@@ -6,9 +6,7 @@
 ### about the specified target
 ###
 
-function( diagnostics_print target_name )
-	build_source_group(${target_name})
-	
+function( diagnostics_print target_name )	
 	message(STATUS "${target_name} settings:")
 	message(STATUS "==============\n")
 
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/aas/api/manager/IAssetAdministrationShellManager.h b/sdks/c++/basys.sdk.cc/include/BaSyx/aas/api/manager/IAssetAdministrationShellManager.h
deleted file mode 100644
index 7ce4948..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/aas/api/manager/IAssetAdministrationShellManager.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * IAssetAdministrationShellManager.h
- *
- *      Author: wendel
- */
-
-#ifndef IASSETADMINISTRATIONSHELLMANAGER_H_
-#define IASSETADMINISTRATIONSHELLMANAGER_H_
-
-#include <string>
-#include "aas/api/metamodel/IAssetAdministrationShell.h"
-#include "aas/map/modelurn/ModelUrn.h"
-#include "submodel/api/ISubModel.h"
-
-namespace basyx {
-namespace aas {
-namespace api {
-namespace manager {
-
-class IAssetAdministrationShellManager
-{
-public:
-  ~IAssetAdministrationShellManager() = default;
-  virtual std::shared_ptr<IAssetAdministrationShell> retrieveAAS(ModelUrn aasUrn) = 0;
-  virtual basyx::specificCollection_t<IAssetAdministrationShell> retrieveAASAll() = 0;
-  virtual void createAAS(std::shared_ptr<IAssetAdministrationShell> aas, ModelUrn urn) = 0;
-  virtual void deleteAAS(std::string id) = 0;
-  virtual std::shared_ptr<submodel::ISubModel> retrieveSubModel(ModelUrn aasUrn, std::string subModelId) = 0;
-  virtual void createSubModel(ModelUrn aasUrn, std::shared_ptr<submodel::ISubModel> submodel) = 0;
-};
-
-}
-}
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/aas/api/metamodel/IAssetAdministrationShell.h b/sdks/c++/basys.sdk.cc/include/BaSyx/aas/api/metamodel/IAssetAdministrationShell.h
deleted file mode 100644
index 999f7cd..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/aas/api/metamodel/IAssetAdministrationShell.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * IAssetAdministrationShell.h
- *
- *      Author: wendel
- */
-
-#ifndef AAS_IASSETADMINISTRATIONSHELL_H_
-#define AAS_IASSETADMINISTRATIONSHELL_H_
-
-#include <BaSyx/submodel/api/qualifier/IHasDataSpecification.h>
-#include <BaSyx/submodel/api/qualifier/IIdentifiable.h>
-#include <BaSyx/submodel/api/qualifier/IReferable.h>
-#include <BaSyx/aas/api/security/ISecurity.h>
-#include <BaSyx/submodel/api/reference/IReference.h>
-
-#include <memory>
-
-namespace basyx {
-namespace aas {
-
-class IAssetAdministrationShell
-  : public virtual submodel::IHasDataSpecification
-  , public virtual submodel::IIdentifiable
-  , public virtual submodel::IReferable
-{
-public:
-  struct Path
-  {
-    static constexpr char ModelType[] = "AssetAdministationShell";
-    static constexpr char Security[] = "security";
-    static constexpr char DerivedFrom[] = "derivedFrom";
-  };
-public:
-  virtual std::shared_ptr<ISecurity> getSecurity() const = 0;
-  virtual void setSecurity(std::shared_ptr<ISecurity> security) const = 0;
-
-  virtual std::shared_ptr<submodel::IReference> getDerivedFrom() const = 0;
-  virtual void setDerivedFrom(std::shared_ptr<submodel::IReference> derived_from) const = 0;
-};
-
-}
-}
-
-#endif
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/aas/api/parts/IAsset.h b/sdks/c++/basys.sdk.cc/include/BaSyx/aas/api/parts/IAsset.h
deleted file mode 100644
index 982869e..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/aas/api/parts/IAsset.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * IAsset.h
- *
- *      Author: wendel
- */ 
-
-#ifndef BASYX_METAMODEL_IAsset_H_
-#define BASYX_METAMODEL_IAsset_H_
-
-
-#include <BaSyx/submodel/api/qualifier/IHasDataSpecification.h>
-#include <BaSyx/submodel/api/qualifier/IHasKind.h>
-#include <BaSyx/submodel/api/qualifier/IIdentifiable.h>
-#include <BaSyx/submodel/api/reference/IReference.h>
-
-namespace basyx {
-namespace aas {
-
-class IAsset :
-	public virtual submodel::IHasDataSpecification,
-	public virtual submodel::IHasKind,
-	public virtual submodel::IIdentifiable
-{
-public:
-  struct Path
-  {
-    static constexpr char AssetIdentificationModel[] = "assetIdentificationModel";
-    static constexpr char ModelType[] = "Asset";
-    static constexpr char BillOfMaterial[] = "billOfMaterial";
-  };
-public:
-	virtual ~IAsset() = default;
-
-	virtual std::shared_ptr<submodel::IReference> getAssetIdentificationModel() const = 0;
-  virtual std::shared_ptr<submodel::IReference> getBillOfMaterial() const = 0;
-};
-
-}
-}
-
-#endif
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/aas/api/parts/IConceptDictionary.h b/sdks/c++/basys.sdk.cc/include/BaSyx/aas/api/parts/IConceptDictionary.h
deleted file mode 100644
index 36a4ac1..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/aas/api/parts/IConceptDictionary.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * IConceptDictionary.h
- *
- *      Author: wendel
- */ 
-
-#ifndef BASYX_METAMODEL_IConceptDictionary_H_
-#define BASYX_METAMODEL_IConceptDictionary_H_
-
-
-#include <BaSyx/submodel/api/qualifier/IReferable.h>
-
-#include <string>
-#include <vector>
-
-namespace basyx {
-namespace aas {
-
-class IConceptDictionary 
-  : public submodel::IReferable
-{
-public:
-  struct Path {
-    static constexpr char ConceptDescription[] = "conceptDescription";
-    static constexpr char ConceptDescriptions[] = "conceptDescriptions";
-  };
-
-  virtual ~IConceptDictionary() = default;
-
-  virtual basyx::specificCollection_t<submodel::IReference> getConceptDescription() const = 0;
-  virtual void setConceptDescription(const basyx::specificCollection_t<submodel::IReference> & references) = 0;
-};
-
-}
-}
-
-#endif
-
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/aas/api/parts/IView.h b/sdks/c++/basys.sdk.cc/include/BaSyx/aas/api/parts/IView.h
deleted file mode 100644
index bbb0c3c..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/aas/api/parts/IView.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * IView.h
- *
- *      Author: wendel
- */ 
-
-#ifndef BASYX_METAMODEL_IView_H_
-#define BASYX_METAMODEL_IView_H_
-
-
-#include <BaSyx/submodel/api/qualifier/IHasSemantics.h>
-#include <BaSyx/submodel/api/qualifier/IHasDataSpecification.h>
-#include <BaSyx/submodel/api/qualifier/IReferable.h>
-#include <BaSyx/submodel/api/reference/IReference.h>
-
-namespace basyx {
-namespace aas {
-
-class IView : 
-	public submodel::IHasDataSpecification,
-	public submodel::IHasSemantics, 
-	public submodel::IReferable
-{
-public:
-  struct Path
-  {
-    static constexpr char ContainedElement[] = "containedElement";
-    static constexpr char ModelType[] = "View";
-  };
-public:
-	virtual ~IView() = default;
-
-	virtual void setContainedElements(const basyx::specificCollection_t<submodel::IReference> & references) = 0;
-	virtual basyx::specificCollection_t<submodel::IReference> getContainedElements() const = 0;
-};
-
-}
-}
-
-#endif
-
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/aas/api/policypoints/IAccessControlPolicyPoints.h b/sdks/c++/basys.sdk.cc/include/BaSyx/aas/api/policypoints/IAccessControlPolicyPoints.h
deleted file mode 100644
index cc0800c..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/aas/api/policypoints/IAccessControlPolicyPoints.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * IAccessControlPolicyPoints.h
- *
- *      Author: wendel
- */ 
-
-#ifndef BASYX_METAMODEL_IAccessControlPolicyPoints_H_
-#define BASYX_METAMODEL_IAccessControlPolicyPoints_H_
-
-
-#include "types/BaSysTypes.h"
-
-class IAccessControlPolicyPoints
-{
-public:
-	virtual ~IAccessControlPolicyPoints() = default;
-
-	virtual void setPolicyAdministrationPoint(const basyx::object & obj) = 0;
-	virtual basyx::object getPolicyAdministrationPoint() const = 0;
-
-	virtual void setPolicyDecisionPoint(const basyx::object & obj) = 0;
-	virtual basyx::object getPolicyDecisionPoint() const = 0;
-
-	virtual void setPolicyEnforcementPoint(const basyx::object & obj) = 0;
-	virtual basyx::object getPolicyEnforcementPoint() const = 0;
-
-	virtual void setPolicyInformationPoints(const basyx::object & obj) = 0;
-	virtual basyx::object getPolicyInformationPoints() const = 0;
-
-};
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/aas/api/security/ISecurity.h b/sdks/c++/basys.sdk.cc/include/BaSyx/aas/api/security/ISecurity.h
deleted file mode 100644
index 3107f30..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/aas/api/security/ISecurity.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * ISecurity.h
- *
- *      Author: wendel
- */ 
-
-#ifndef BASYX_METAMODEL_ISecurity_H_
-#define BASYX_METAMODEL_ISecurity_H_
-
-#include <BaSyx/shared/types.h>
-#include <BaSyx/shared/object.h>
-
-namespace basyx {
-namespace aas {
-
-class ISecurity
-{
-public:
-  struct Path
-  {
-    static constexpr char AccessControlPolicyPoints[] = "accessControlPolicyPoints";
-    static constexpr char TrustAnchor[] = "trustAnchor";
-  };
-public:
-  virtual ~ISecurity() = default;
-
-  virtual basyx::object getAccessControlPolicyPoints() const = 0;
-  virtual basyx::object getTrustAnchor() const = 0;
-};
-
-}
-}
-
-#endif
-
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/aas/connected/ConnectedAssetAdministrationShell.h b/sdks/c++/basys.sdk.cc/include/BaSyx/aas/connected/ConnectedAssetAdministrationShell.h
deleted file mode 100644
index 736bae6..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/aas/connected/ConnectedAssetAdministrationShell.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * ConnectedAssetAdministrationShell.h
- *
- *      Author: wendel
- */
-
-#ifndef AAS_BACKEND_CONNECTED_CONNECTEDASSETADMINISTRATIONSHELL_H_
-#define AAS_BACKEND_CONNECTED_CONNECTEDASSETADMINISTRATIONSHELL_H_
-
-#include "aas/api/metamodel/IAssetAdministrationShell.h"
-#include "submodel/connected/ConnectedVABModelMap.h"
-#include "aas/api/manager/IAssetAdministrationShellManager.h"
-
-namespace basyx {
-namespace aas {
-namespace backend {
-
-class ConnectedAssetAdministrationShell : public api::IAssetAdministrationShell, public submodel::backend::ConnectedVABModelMap
-{
-public:
-  ConnectedAssetAdministrationShell(std::shared_ptr<vab::core::proxy::IVABElementProxy> proxy, std::shared_ptr<api::manager::IAssetAdministrationShellManager> manager);
-	~ConnectedAssetAdministrationShell() = default;
-
-private:
-  std::shared_ptr<api::manager::IAssetAdministrationShellManager> manager;
-
-  // Inherited via IAssetAdministrationShell
-  virtual basyx::specificCollection_t<submodel::IReference> getDataSpecificationReferences() const override;
-  virtual std::string getIdShort() const override;
-  virtual std::string getCategory() const override;
-  virtual submodel::Description getDescription() const override;
-  virtual std::shared_ptr<submodel::IReference> getParent() const override;
-  virtual std::shared_ptr<submodel::IAdministrativeInformation> getAdministration() const override;
-  virtual std::shared_ptr<submodel::IIdentifier> getIdentification() const override;
-  virtual basyx::specificMap_t<submodel::ISubModel> getSubModels() const override;
-  virtual void addSubModel(const descriptor::SubModelDescriptor & subModelDescriptor) override;
-  virtual std::shared_ptr<security::ISecurity> getSecurity() const override;
-  virtual std::shared_ptr<submodel::IReference> getDerivedFrom() const override;
-  virtual std::shared_ptr<aas::IAsset> getAsset() const override;
-  virtual void setSubmodels(const basyx::specificCollection_t<descriptor::SubModelDescriptor> & submodels) override;
-  virtual basyx::specificCollection_t<descriptor::SubModelDescriptor> getSubModelDescriptors() const override;
-  virtual basyx::specificCollection_t<IView> getViews() const override;
-  virtual basyx::specificCollection_t<IConceptDictionary> getConceptDictionary() const override;
-};
-
-}
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/aas/connected/ConnectedAssetAdministrationShellManager.h b/sdks/c++/basys.sdk.cc/include/BaSyx/aas/connected/ConnectedAssetAdministrationShellManager.h
deleted file mode 100644
index 0d15cb2..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/aas/connected/ConnectedAssetAdministrationShellManager.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * ConnectedAssetAdministrationShellManager.h
- *
- *      Author: wendel
- */
-
-#ifndef AAS_BACKEND_CONNECTED_CONNECTEDASSETADMINISTRATIONSHELLMANAGER_H_
-#define AAS_BACKEND_CONNECTED_CONNECTEDASSETADMINISTRATIONSHELLMANAGER_H_
-
-class ConnectedAssetAdministrationShellManager
-{
-public:
-	~ConnectedAssetAdministrationShellManager();
-};
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/aas/map/descriptor/ModelDescriptor.h b/sdks/c++/basys.sdk.cc/include/BaSyx/aas/map/descriptor/ModelDescriptor.h
deleted file mode 100644
index fffde9a..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/aas/map/descriptor/ModelDescriptor.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * ModelDescriptor.h
- *
- *      Author: wendel
- */
-
-#ifndef AAS_IMPL_METAMODEL_HASHMAP_DESCRIPTOR_MODELDESCRIPTOR_H_
-#define AAS_IMPL_METAMODEL_HASHMAP_DESCRIPTOR_MODELDESCRIPTOR_H_
-
-#include <string>
-
-#include <BaSyx/shared/types.h>
-#include <BaSyx/shared/object.h>
-
-#include <BaSyx/submodel/api/identifier/IIdentifier.h>
-
-namespace basyx {
-namespace aas {
-
-class ModelDescriptor
-{
-public:
-  ~ModelDescriptor() = default;
-  ModelDescriptor(basyx::object map);
-
-  /**
-   * Create a new descriptor with minimal information
-   */
-  ModelDescriptor(std::string idShort, std::shared_ptr<submodel::IIdentifier> id, std::string httpEndpoint);
-
-  /**
-   * Return AAS ID
-   */
-  std::shared_ptr<submodel::IIdentifier> getIdentifier();
-
-  /**
-   * Return first AAS endpoint
-   */
-  std::string getFirstEndpoint();
-
-  /**
-   * Return all AAS endpoints
-   */
-  basyx::object::list_t<basyx::object::object_map_t> getEndpoints();
-
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/aas/map/descriptor/SubModelDescriptor.h b/sdks/c++/basys.sdk.cc/include/BaSyx/aas/map/descriptor/SubModelDescriptor.h
deleted file mode 100644
index 241448e..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/aas/map/descriptor/SubModelDescriptor.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * SubModelDescriptor.h
- *
- *      Author: wendel
- */
-
-#ifndef AAS_IMPL_METAMODEL_HASHMAP_DESCRIPTOR_SUBMODELDESCRIPTOR_H_
-#define AAS_IMPL_METAMODEL_HASHMAP_DESCRIPTOR_SUBMODELDESCRIPTOR_H_
-
-#include "ModelDescriptor.h"
-
-#include <BaSyx/submodel/api/ISubModel.h>
-
-namespace basyx {
-namespace aas {
-namespace descriptor {
-
-class SubModelDescriptor : public ModelDescriptor
-{
-public:
-  ~SubModelDescriptor() = default;
-
-  SubModelDescriptor(basyx::object::object_map_t map);
-
-  /**
-   * Create a new aas descriptor with minimal information based on an existing
-   * submodel.
-  */
-  SubModelDescriptor(std::shared_ptr<submodel::ISubModel> subModel, std::string httpEndpoint);
-
-  /**
-   * Create a new descriptor with minimal information
-   */
-  SubModelDescriptor(std::string idShort, std::shared_ptr<submodel::IIdentifier> identifier, std::string httpEndpoint);
-};
-
-}
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/aas/map/manager/AssetAdministrationShellManager.h b/sdks/c++/basys.sdk.cc/include/BaSyx/aas/map/manager/AssetAdministrationShellManager.h
deleted file mode 100644
index 661c2c5..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/aas/map/manager/AssetAdministrationShellManager.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * AssetAdministrationShellManager.h
- *
- *      Author: wendel
- */
-
-#ifndef ASSETADMINISTRATIONSHELLMANAGER_H_
-#define ASSETADMINISTRATIONSHELLMANAGER_H_
-
-class AssetAdministrationShellManager
-{
-public:
-	~AssetAdministrationShellManager() = default;
-};
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/aas/map/metamodel/AssetAdministrationShell.h b/sdks/c++/basys.sdk.cc/include/BaSyx/aas/map/metamodel/AssetAdministrationShell.h
deleted file mode 100644
index 3b2359a..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/aas/map/metamodel/AssetAdministrationShell.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * AssetAdministrationShell.h
- *
- *      Author: wendel
- */
-
-#ifndef AAS_IMPL_METAMODEL_HASHMAP_ASSETADMINISTRATIONSHELL_H_
-#define AAS_IMPL_METAMODEL_HASHMAP_ASSETADMINISTRATIONSHELL_H_
-
-#include <BaSyx/aas/api/metamodel/IAssetAdministrationShell.h>
-
-#include <BaSyx/submodel/map/qualifier/HasDataSpecification.h>
-#include <BaSyx/submodel/map/qualifier/Identifiable.h>
-#include <BaSyx/submodel/map/qualifier/Referable.h>
-#include <BaSyx/submodel/map/modeltype/ModelType.h>
-
-#include <BaSyx/shared/object.h>
-#include <BaSyx/vab/ElementMap.h>
-
-namespace basyx {
-namespace aas {
-
-class AssetAdministrationShell 
-  : public IAssetAdministrationShell
-  , public virtual vab::ElementMap
-  , public virtual submodel::HasDataSpecification
-  , public virtual submodel::Identifiable
-  , public virtual submodel::Referable
-  , public virtual submodel::ModelType
-{
-public:
-  ~AssetAdministrationShell() = default;
-
-  // constructors
-  AssetAdministrationShell();
-  AssetAdministrationShell(basyx::object obj);
-  AssetAdministrationShell(std::shared_ptr<submodel::IReference> parentAAS);
-  
-  // Inherited via IAssetAdministrationShell
-  virtual std::shared_ptr<ISecurity> getSecurity() const override;
-  virtual void setSecurity(std::shared_ptr<ISecurity> security) const override;
-  virtual std::shared_ptr<submodel::IReference> getDerivedFrom() const override;
-  virtual void setDerivedFrom(std::shared_ptr<submodel::IReference> derived_from) const override;
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/aas/map/modelurn/ModelUrn.h b/sdks/c++/basys.sdk.cc/include/BaSyx/aas/map/modelurn/ModelUrn.h
deleted file mode 100644
index 1210e66..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/aas/map/modelurn/ModelUrn.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * ModelUrn.h
- *
- *      Author: wendel
- */
-
-#ifndef MODELURN_H_
-#define MODELURN_H_
-
-class ModelUrn
-{
-public:
-	~ModelUrn();
-};
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/aas/map/parts/Asset.h b/sdks/c++/basys.sdk.cc/include/BaSyx/aas/map/parts/Asset.h
deleted file mode 100644
index d5dcffd..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/aas/map/parts/Asset.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Asset.h
- *
- *      Author: wendel
- */
-
-#ifndef AAS_IMPL_METAMODEL_HASHMAP_PARTS_ASSET_H_
-#define AAS_IMPL_METAMODEL_HASHMAP_PARTS_ASSET_H_
-
-#include <BaSyx/aas/api/parts/IAsset.h>
-
-#include <BaSyx/submodel/map/qualifier/HasDataSpecification.h>
-#include <BaSyx/submodel/map/qualifier/HasKind.h>
-#include <BaSyx/submodel/map/qualifier/Identifiable.h>
-#include <BaSyx/submodel/map/modeltype/ModelType.h>
-
-namespace basyx {
-namespace aas {
-
-class Asset 
-  : public IAsset
-  , public virtual submodel::HasKind
-  , public virtual submodel::HasDataSpecification
-  , public virtual submodel::Identifiable
-  , public virtual submodel::ModelType
-{
-public:
-  ~Asset() = default;
-
-  // constructors
-  Asset();
-
-  /**
-   *
-   * @param submodel A reference to a Submodel that defines the handling of
-   *                 additional domain specific (proprietary) Identifiers for the
-   *                 asset like e.g. serial number etc.
-  */
-  Asset(const std::shared_ptr<submodel::IReference> & submodel);
-   
-  // Inherited via IAsset
-  virtual std::shared_ptr<submodel::IReference> getAssetIdentificationModel() const override;
-  virtual std::shared_ptr<submodel::IReference> getBillOfMaterial() const override;
-
-
-  void setAssetIdentificationModel(const std::shared_ptr<submodel::IReference>& submodel);
-  void setBillOfMaterial(const std::shared_ptr<submodel::IReference>& submodel);
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/aas/map/parts/ConceptDictionary.h b/sdks/c++/basys.sdk.cc/include/BaSyx/aas/map/parts/ConceptDictionary.h
deleted file mode 100644
index 82c923b..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/aas/map/parts/ConceptDictionary.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * ConceptDictionary.h
- *
- *      Author: wendel
- */
-
-#ifndef AAS_IMPL_METAMODEL_HASHMAP_PARTS_CONCEPTDICTIONARY_H_
-#define AAS_IMPL_METAMODEL_HASHMAP_PARTS_CONCEPTDICTIONARY_H_
-
-#include <BaSyx/aas/api/parts/IConceptDictionary.h>
-
-#include <BaSyx/submodel/api/parts/IConceptDescription.h>
-#include <BaSyx/submodel/map/qualifier/Referable.h>
-
-namespace basyx {
-namespace aas {
-
-class ConceptDictionary 
-  : public virtual IConceptDictionary
-  , public virtual submodel::Referable
-  , public virtual basyx::vab::ElementMap
-{
-public:
-  ~ConceptDictionary() = default;
-
-  ConceptDictionary(basyx::object obj);
-  ConceptDictionary(basyx::specificCollection_t<submodel::IReference> concept_descriptions);
-
-
-  // Inherited via IConceptDictionary
-  virtual basyx::specificCollection_t<submodel::IReference> getConceptDescription() const override;
-  virtual void setConceptDescription(const basyx::specificCollection_t<submodel::IReference> & references) override;
-
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/aas/map/parts/View.h b/sdks/c++/basys.sdk.cc/include/BaSyx/aas/map/parts/View.h
deleted file mode 100644
index 4f2981d..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/aas/map/parts/View.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * View.h
- *
- *      Author: wendel
- */
-
-#ifndef AAS_IMPL_METAMODEL_HASHMAP_PARTS_VIEW_H_
-#define AAS_IMPL_METAMODEL_HASHMAP_PARTS_VIEW_H_
-
-#include <BaSyx/aas/api/parts/IView.h>
-
-#include <BaSyx/submodel/map/modeltype/ModelType.h>
-#include <BaSyx/submodel/map/qualifier/HasDataSpecification.h>
-#include <BaSyx/submodel/map/qualifier/Referable.h>
-#include <BaSyx/submodel/map/qualifier/HasSemantics.h>
-
-namespace basyx {
-namespace aas {
-
-class View 
-  : public IView
-  , public virtual vab::ElementMap
-  , public virtual submodel::ModelType
-  , public virtual submodel::HasDataSpecification
-  , public virtual submodel::HasSemantics
-{
-public:
-  ~View() = default;
-
-  View(basyx::object obj);
-  View();
-  View(const basyx::specificCollection_t<submodel::IReference> & references);
-
-  // Inherited via IView
-  virtual void setContainedElements(const basyx::specificCollection_t<submodel::IReference> & references) override;
-  virtual basyx::specificCollection_t<submodel::IReference> getContainedElements() const override;
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/aas/map/security/Security.h b/sdks/c++/basys.sdk.cc/include/BaSyx/aas/map/security/Security.h
deleted file mode 100644
index 86b17b8..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/aas/map/security/Security.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Security.h
- *
- *      Author: wendel
- */
-
-#ifndef AAS_IMPL_METAMODEL_HASHMAP_SECURITY_SECURITY_H_
-#define AAS_IMPL_METAMODEL_HASHMAP_SECURITY_SECURITY_H_
-
-#include <BaSyx/aas/api/security/ISecurity.h>
-
-#include <BaSyx/shared/types.h>
-
-#include <BaSyx/vab/ElementMap.h>
-
-namespace basyx {
-namespace aas {
-
-class Security 
-  : public ISecurity
-  , public virtual vab::ElementMap
-{
-public:
-  ~Security() = default;
-
-  Security(ISecurity & other);
-  Security(basyx::object obj);
-
-  // Inherited via ISecurity
-  virtual basyx::object getAccessControlPolicyPoints() const override;
-  virtual basyx::object getTrustAnchor() const override;
-
-  void setAccessControlPolicyPoints(const basyx::object & obj);
-  void setTrustAnchor(const basyx::object & obj);
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/Net.h b/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/Net.h
index 4fe62bd..f1bd828 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/Net.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/Net.h
@@ -1,3 +1,6 @@
+#ifndef BASYX_ABSTRACTION_NET_H
+#define BASYX_ABSTRACTION_NET_H
+
 /*
  * Net.h
  *
@@ -9,3 +12,5 @@
 #include <BaSyx/abstraction/net/Acceptor.h>
 #include <BaSyx/abstraction/net/Buffer.h>
 #include <BaSyx/abstraction/net/Socket.h>
+
+#endif /* BASYX_ABSTRACTION_NET_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/Thread.h b/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/Thread.h
index 6509c16..4b2dfc3 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/Thread.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/Thread.h
@@ -1,3 +1,6 @@
+#ifndef BASYX_ABSTRACTION_THREAD_H
+#define BASYX_ABSTRACTION_THREAD_H
+
 /*
  * Thread.h
  *
@@ -6,3 +9,5 @@
  */
 
 #include <BaSyx/abstraction/thread/Thread.h>
+
+#endif /* BASYX_ABSTRACTION_THREAD_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/impl/acceptor_impl.h b/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/impl/acceptor_impl.h
index 5b79cd7..58c3b00 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/impl/acceptor_impl.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/impl/acceptor_impl.h
@@ -1,12 +1,5 @@
-/*
- * Socket.h
- *
- *  Created on: 06.11.2018
- *      Author: schnicke
- */
-
-#ifndef ABSTRACTION_ACCEPTOR_IMPL_H_
-#define ABSTRACTION_ACCEPTOR_IMPL_H_
+#ifndef BASYX_ABSTRACTION_IMPL_ACCEPTOR_IMPL_H
+#define BASYX_ABSTRACTION_IMPL_ACCEPTOR_IMPL_H
 
 #include <cstdlib>
 
@@ -18,34 +11,34 @@
 #include <BaSyx/log/log.h>
 
 namespace basyx {
-	namespace net {
-		namespace impl {
+namespace net {
+namespace impl {
 
-			// Forward declarations
-			class socket_impl;
+// Forward declarations
+class socket_impl;
 
-			class acceptor_impl 
-			{
-			public:
-				acceptor_impl()
-					: log{ "AcceptorImpl" } {};
-				~acceptor_impl();
-			public:
-				int listen(const std::string & port);
+class acceptor_impl {
+public:
+    acceptor_impl()
+        : log { "AcceptorImpl" } {};
+    ~acceptor_impl();
 
-				std::unique_ptr<socket_impl> accept();
-				int shutdown(enum SocketShutdownDir how);
-				int close();
+public:
+    int listen(const std::string& port);
 
-				int getErrorCode();
-			private:
-				native_socket_type socketDesc = 0;
-				basyx::log log;
-			};
+    std::unique_ptr<socket_impl> accept();
+    int shutdown(enum SocketShutdownDir how);
+    int close();
 
+    int getErrorCode();
 
-		}
-	}
+private:
+    native_socket_type socketDesc = 0;
+    basyx::log log;
+};
+
+}
+}
 }
 
-#endif /* ABSTRACTION_ACCEPTOR_IMPL_H_ */
+#endif /* BASYX_ABSTRACTION_IMPL_ACCEPTOR_IMPL_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/impl/socket_impl.h b/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/impl/socket_impl.h
index 4cba639..30ae729 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/impl/socket_impl.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/impl/socket_impl.h
@@ -1,12 +1,5 @@
-/*
- * Socket.h
- *
- *  Created on: 06.11.2018
- *      Author: schnicke
- */
-
-#ifndef ABSTRACTION_SOCKET_IMPL_H_
-#define ABSTRACTION_SOCKET_IMPL_H_
+#ifndef BASYX_ABSTRACTION_IMPL_SOCKET_IMPL_H
+#define BASYX_ABSTRACTION_IMPL_SOCKET_IMPL_H
 
 #include <BaSyx/abstraction/impl/system_net_types.h>
 
@@ -17,32 +10,33 @@
 
 namespace basyx {
 namespace net {
-    namespace impl {
+namespace impl {
 
-        class socket_impl 
-        {
-        private:
-            native_socket_type SocketDesc;
-            basyx::log log;
-        public:
-            socket_impl();
-            
-            explicit socket_impl(native_socket_type socket);
-            
-            ~socket_impl();
+class socket_impl 
+{
+private:
+    native_socket_type SocketDesc;
+    basyx::log log;
+public:
+    socket_impl();
+    
+    explicit socket_impl(native_socket_type socket);
+    
+    ~socket_impl();
 
-        public:
-            int connect(std::string const&, std::string const&);
-            int read(void*, size_t);
-            int recv(void*, size_t, int);
-            int write(void*, size_t);
+public:
+    int connect(std::string const&, std::string const&);
+    int read(void*, size_t);
+    int recv(void*, size_t, int);
+    int write(void*, size_t);
 
-            int shutdown(enum SocketShutdownDir how);
-            int close();
+    int shutdown(enum SocketShutdownDir how);
+    int close();
 
-            int getErrorCode();
-        };
-    }
+    int getErrorCode();
+};
+
 }
 }
-#endif /* ABSTRACTION_SOCKET_IMPL_H_ */
+}
+#endif /* BASYX_ABSTRACTION_IMPL_SOCKET_IMPL_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/impl/system_net_types.h b/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/impl/system_net_types.h
index 5af9050..fa0d7c3 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/impl/system_net_types.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/impl/system_net_types.h
@@ -1,5 +1,5 @@
-#ifndef ABSTRACTION_SYSTEM_NET_TYPES_H
-#define ABSTRACTION_SYSTEM_NET_TYPES_H
+#ifndef BASYX_ABSTRACTION_IMPL_SYSTEM_NET_TYPES_H
+#define BASYX_ABSTRACTION_IMPL_SYSTEM_NET_TYPES_H
 
 #ifdef _WIN32
 	#if _WIN32_WINNT <= 0x501
@@ -31,4 +31,4 @@
 	};
 #endif
 
-#endif
+#endif /* BASYX_ABSTRACTION_IMPL_SYSTEM_NET_TYPES_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/impl/thread_impl.h b/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/impl/thread_impl.h
index 2d2567f..00724f9 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/impl/thread_impl.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/impl/thread_impl.h
@@ -1,5 +1,5 @@
-#ifndef ABSTRACTION_IMPL_THREAD_H
-#define ABSTRACTION_IMPL_THREAD_H
+#ifndef BASYX_ABSTRACTION_IMPL_THREAD_IMPL_H
+#define BASYX_ABSTRACTION_IMPL_THREAD_IMPL_H
 
 #ifdef _WIN32
 #include <BaSyx/abstraction/impl/windows/thread/thread_impl.h>
@@ -7,4 +7,4 @@
 #include <BaSyx/abstraction/impl/unix/thread/thread_impl.h>
 #endif
 
-#endif
+#endif /* BASYX_ABSTRACTION_IMPL_THREAD_IMPL_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/impl/thread_launcher.h b/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/impl/thread_launcher.h
index 633d393..8732f21 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/impl/thread_launcher.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/impl/thread_launcher.h
@@ -5,8 +5,8 @@
  *      Author: psota
  */
 
-#ifndef UTIL_THREADIMPL_H
-#define UTIL_THREADIMPL_H
+#ifndef BASYX_ABSTRACTION_IMPL_THREAD_LAUNCHER_H
+#define BASYX_ABSTRACTION_IMPL_THREAD_LAUNCHER_H
 
 #define USE_STD_ATOMIC
 //#define USE_STD_INVOKE
@@ -30,83 +30,86 @@
 #endif
 
 namespace basyx {
-	namespace detail
-	{
-		template<class Func, typename... Args>
-		class Thread_Launcher
-		{
-		private:
+namespace detail {
+
+template <class Func, typename... Args>
+class Thread_Launcher {
+private:
 #ifdef USE_STD_ATOMIC
-			std::atomic_flag not_started_lock = ATOMIC_FLAG_INIT;
+    std::atomic_flag not_started_lock = ATOMIC_FLAG_INIT;
 #else
-			bool started = false;
+    bool started = false;
 #endif
-		private:
-			struct target
-			{
-				util::decay_t<Func> f;
-				std::tuple<util::decay_t<Args>...> args;
+private:
+    struct target {
+        util::decay_t<Func> f;
+        std::tuple<util::decay_t<Args>...> args;
 
-				template<class OtherFunc, typename... OtherArgs>
-				target(OtherFunc && f, OtherArgs && ... args)
-					: f{ std::forward<OtherFunc>(f) }
-					, args{ std::make_tuple<OtherArgs...>(std::forward<OtherArgs>(args)...) }
-				{
-				}
+        template <class OtherFunc, typename... OtherArgs>
+        target(OtherFunc&& f, OtherArgs&&... args)
+            : f { std::forward<OtherFunc>(f) }
+            , args { std::make_tuple<OtherArgs...>(std::forward<OtherArgs>(args)...) }
+        {
+        }
 
-				inline void dispatch() {
-					callFunc(typename util::meta::generator_sequence<sizeof...(Args)>::type());
-				}
+        inline void dispatch()
+        {
+            callFunc(typename util::meta::generator_sequence<sizeof...(Args)>::type());
+        }
 
-				template<int... tail>
-				inline void callFunc(util::meta::sequence<tail...>) {
+        template <int... tail>
+        inline void callFunc(util::meta::sequence<tail...>)
+        {
 #ifdef USE_STD_INVOKE
-					std::invoke(std::forward<util::decay_t<Func>>(f), std::get<tail>(args)...);
+            std::invoke(std::forward<util::decay_t<Func>>(f), std::get<tail>(args)...);
 #else
-					util::invoke(std::forward<util::decay_t<Func>>(f), std::get<tail>(args)...);
+            util::invoke(std::forward<util::decay_t<Func>>(f), std::get<tail>(args)...);
 #endif
-				}
-			};
+        }
+    };
 
-			std::unique_ptr<target> targetPtr;
-		private:
-			static unsigned BASYX_THREAD_CALL_CONVENTION launch_internal(void * this_ptr)
-			{
-				auto _this = static_cast<Thread_Launcher<Func, Args...>*>(this_ptr);
-				auto _target = std::forward<std::unique_ptr<target>>(_this->targetPtr);
+    std::unique_ptr<target> targetPtr;
+
+private:
+    static unsigned BASYX_THREAD_CALL_CONVENTION launch_internal(void* this_ptr)
+    {
+        auto _this = static_cast<Thread_Launcher<Func, Args...>*>(this_ptr);
+        auto _target = std::forward<std::unique_ptr<target>>(_this->targetPtr);
 #ifdef USE_STD_ATOMIC
-				_this->not_started_lock.clear(std::memory_order_release);
+        _this->not_started_lock.clear(std::memory_order_release);
 #else
-				_this->started = true;
+        _this->started = true;
 #endif
-				_target->dispatch();
-				return 0;
-			};
-		public:
-			explicit Thread_Launcher(Func && f, Args && ... args)
-				: targetPtr{ util::make_unique<target>(std::forward<Func>(f), std::forward<Args>(args)...) }
-			{
+        _target->dispatch();
+        return 0;
+    };
+
+public:
+    explicit Thread_Launcher(Func&& f, Args&&... args)
+        : targetPtr { util::make_unique<target>(std::forward<Func>(f), std::forward<Args>(args)...) }
+    {
 #ifdef USE_STD_ATOMIC
-				not_started_lock.test_and_set(std::memory_order_acquire);
+        not_started_lock.test_and_set(std::memory_order_acquire);
 #endif
-			}
+    }
 
-			template<typename T, typename D, template<typename, typename> class thrd_impl >
-			inline void Launch(thrd_impl<T,D> & thrd)
-			{
-				thrd = util::make_unique<T>(Thread_Launcher<Func, Args...>::launch_internal, this);
-				thrd->run();
+    template <typename T, typename D, template <typename, typename> class thrd_impl>
+    inline void Launch(thrd_impl<T, D>& thrd)
+    {
+        thrd = util::make_unique<T>(Thread_Launcher<Func, Args...>::launch_internal, this);
+        thrd->run();
 
-				// spinlock until thread is started
+        // spinlock until thread is started
 #ifdef USE_STD_ATOMIC
-				while (this->not_started_lock.test_and_set(std::memory_order_acquire))
+        while (this->not_started_lock.test_and_set(std::memory_order_acquire))
 #else
-				while (!started)
+        while (!started)
 #endif
-					; // spin
-			};
-		};
-	}
+        /* spin */   ; // do nothing
+    };
 };
 
-#endif
+}
+}
+
+#endif /* BASYX_ABSTRACTION_IMPL_THREAD_LAUNCHER_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/impl/unix/thread/thread_impl.h b/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/impl/unix/thread/thread_impl.h
index c8b5700..4d02a96 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/impl/unix/thread/thread_impl.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/impl/unix/thread/thread_impl.h
@@ -5,8 +5,8 @@
  *      Author: cgries
  */
 
-#ifndef ABSTRACTION_UNIX_THREAD_BASYXTHREAD_H_
-#define ABSTRACTION_UNIX_THREAD_BASYXTHREAD_H_
+#ifndef BASYX_ABSTRACTION_IMPL_UNIX_THREAD_THREAD_IMPL_H
+#define BASYX_ABSTRACTION_IMPL_UNIX_THREAD_THREAD_IMPL_H
 
 #include <pthread.h>
 
@@ -15,25 +15,25 @@
 namespace basyx {
 namespace detail {
 
-    class thread_impl 
-    {
-    public:
-        thread_impl(unsigned int (*)(void*), void*);
-        ~thread_impl();
+class thread_impl {
+public:
+    thread_impl(unsigned int (*)(void*), void*);
+    ~thread_impl();
 
-        int run();
-        int join();
-        int detach();
+    int run();
+    int join();
+    int detach();
 
-    private:
-        pthread_t threadDesc;
-        unsigned int (*threadFn)(void*);
-        void* threadArg;
+private:
+    pthread_t threadDesc;
+    unsigned int (*threadFn)(void*);
+    void* threadArg;
 
-    public:
-        static int getCurrentThreadId();
-    };
+public:
+    static int getCurrentThreadId();
+};
+
 }
 }
 
-#endif /* ABSTRACTION_UNIX_THREAD_BASYXTHREAD_H_ */
+#endif /* BASYX_ABSTRACTION_IMPL_UNIX_THREAD_THREAD_IMPL_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/impl/windows/thread/thread_impl.h b/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/impl/windows/thread/thread_impl.h
index 07975d7..0b42015 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/impl/windows/thread/thread_impl.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/impl/windows/thread/thread_impl.h
@@ -5,36 +5,36 @@
  *      Author: cgries
  */
 
-#ifndef ABSTRACTION_UNIX_THREAD_BASYXTHREAD_H_
-#define ABSTRACTION_UNIX_THREAD_BASYXTHREAD_H_
+#ifndef BASYX_ABSTRACTION_IMPL_WINDOWS_THREAD_THREAD_IMPL_H
+#define BASYX_ABSTRACTION_IMPL_WINDOWS_THREAD_THREAD_IMPL_H
 
 #include <process.h>
 #include <windows.h>
 
 namespace basyx {
-	namespace detail {
+namespace detail {
 
-		class thread_impl {
+class thread_impl 
+{
+public:
+    thread_impl(unsigned int(__stdcall*)(void*), void*);
+    ~thread_impl();
 
-		public:
-			thread_impl(unsigned int (__stdcall *)(void*), void*);
-			~thread_impl();
+    int run();
+    int join();
+    int detach();
 
-			int run();
-			int join();
-			int detach();
+private:
+    HANDLE threadDesc;
+    unsigned int threadID;
+    unsigned int(__stdcall* threadFn)(void*);
+    void* threadArg;
 
-		private:
-			HANDLE threadDesc;
-			unsigned int threadID;
-			unsigned int (__stdcall *threadFn) (void*);
-			void* threadArg;
-		public:
-			static int getCurrentThreadId();
-		};
-	}
+public:
+    static int getCurrentThreadId();
+};
+
+}
 }
 
-
-
-#endif /* ABSTRACTION_UNIX_THREAD_BASYXTHREAD_H_ */
+#endif /* BASYX_ABSTRACTION_IMPL_WINDOWS_THREAD_THREAD_IMPL_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/net/Acceptor.h b/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/net/Acceptor.h
index aec07aa..83815e5 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/net/Acceptor.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/net/Acceptor.h
@@ -5,52 +5,53 @@
  *      Author: psota
  */
 
-#ifndef ABSTRACTION_NET_ACCEPTOR_H_
-#define ABSTRACTION_NET_ACCEPTOR_H_
+#ifndef BASYX_ABSTRACTION_NET_ACCEPTOR_H
+#define BASYX_ABSTRACTION_NET_ACCEPTOR_H
 
-#include <memory>
 #include <BaSyx/log/log.h>
+#include <memory>
 
 #include <BaSyx/abstraction/net/Socket.h>
 
 namespace basyx {
-	namespace net {
-		
-		// Forward declarations
-		namespace impl {
-			class acceptor_impl;
-		}
+namespace net {
 
-		namespace tcp {
-
-			class Acceptor
-			{
-			private:
-				std::unique_ptr<basyx::net::impl::acceptor_impl> acceptor;
-				basyx::log log;
-				Acceptor & _move_acceptor(Acceptor && other);
-			public:
-				explicit Acceptor(int port);
-				explicit Acceptor(const std::string & port);
-
-				// Delete copy-assignment and constructor, there should only ever be one Acceptor object representing a single acceptor
-				Acceptor(const Acceptor & other) = delete;
-				Acceptor& operator=(const Acceptor & other) = delete;
-
-				// Allow move-operations
-				Acceptor & operator=(Acceptor && other);
-				Acceptor(Acceptor && other);
-
-				~Acceptor();
-			public:
-				void close();
-
-				// Blockingly wait for connection
-				Socket accept();
-			};
-		}
-	}
+// Forward declarations
+namespace impl {
+    class acceptor_impl;
 }
 
+namespace tcp {
 
-#endif
+    class Acceptor {
+    private:
+        std::unique_ptr<basyx::net::impl::acceptor_impl> acceptor;
+        basyx::log log;
+        Acceptor& _move_acceptor(Acceptor&& other);
+
+    public:
+        explicit Acceptor(int port);
+        explicit Acceptor(const std::string& port);
+
+        // Delete copy-assignment and constructor, there should only ever be one Acceptor object representing a single acceptor
+        Acceptor(const Acceptor& other) = delete;
+        Acceptor& operator=(const Acceptor& other) = delete;
+
+        // Allow move-operations
+        Acceptor& operator=(Acceptor&& other);
+        Acceptor(Acceptor&& other);
+
+        ~Acceptor();
+
+    public:
+        void close();
+
+        // Blockingly wait for connection
+        Socket accept();
+    };
+}
+
+}
+}
+
+#endif /* BASYX_ABSTRACTION_NET_ACCEPTOR_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/net/Buffer.h b/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/net/Buffer.h
index 4d1da9b..46ac5ea 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/net/Buffer.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/net/Buffer.h
@@ -1,71 +1,71 @@
 /*
- * Socket.h
- *
- *  Created on: 05.02.2018
- *      Author: psota
- */
+* Socket.h
+*
+*  Created on: 05.02.2018
+*      Author: psota
+*/
 
-#ifndef ABSTRACTION_NET_BUFFER_H_
-#define ABSTRACTION_NET_BUFFER_H_
+#ifndef BASYX_ABSTRACTION_NET_BUFFER_H
+#define BASYX_ABSTRACTION_NET_BUFFER_H
 
-#include <string>
 #include <cstddef>
+#include <string>
 
 namespace basyx {
-	namespace net {
+namespace net {
 
-		class Buffer
-		{
-		private:
-			void * _data;
-			std::size_t _size;
-		public:
-			// Creates a non-owning representation of a block of memory
-			Buffer(void*data, std::size_t size)
-				: _size(size), _data(data)
-			{};
-			~Buffer() = default;
+class Buffer {
+private:
+    void* _data;
+    std::size_t _size;
 
-			// Since this is just using an observing pointer and doesn't own any memory, it is cheap to copy/move
-			// Copy operations
-			Buffer(Buffer & other) = default;
-			Buffer & operator=(Buffer & other) = default;
+public:
+    // Creates a non-owning representation of a block of memory
+    Buffer(void* data, std::size_t size)
+        : _size(size)
+        , _data(data) {};
+    ~Buffer() = default;
 
-			// Move operations
-			Buffer(Buffer && other) = default;
-			Buffer & operator=(Buffer && other) = default;
-		public:
-			inline void * data() const { return _data; };
-			inline std::size_t size() const { return _size; };
-		};
+    // Since this is just using an observing pointer and doesn't own any memory, it is cheap to copy/move
+    // Copy operations
+    Buffer(Buffer& other) = default;
+    Buffer& operator=(Buffer& other) = default;
 
-		template<typename T>
-		Buffer make_buffer(T & t)
-		{
-			return Buffer{ &t, sizeof(T) };
-		};
+    // Move operations
+    Buffer(Buffer&& other) = default;
+    Buffer& operator=(Buffer&& other) = default;
 
-		template<class CharT, class Traits, class Allocator>
-		const Buffer make_buffer(std::basic_string<CharT, Traits, Allocator> & string)
-		{
-			return Buffer{ (void*)string.data(), string.size() * sizeof(CharT) };
-		};
+public:
+    inline void* data() const { return _data; };
+    inline std::size_t size() const { return _size; };
+};
 
-		template<typename T, std::size_t N>
-		Buffer make_buffer(const T(&data)[N])
-		{
-			return Buffer{ data, N * sizeof(T) };
-		}
+template <typename T>
+Buffer make_buffer(T& t)
+{
+    return Buffer { &t, sizeof(T) };
+};
 
-		template<typename T>
-		Buffer make_buffer(T * data, std::size_t size)
-		{
-			return Buffer{ reinterpret_cast<void*>(data), size };
-		}
+template <class CharT, class Traits, class Allocator>
+const Buffer make_buffer(std::basic_string<CharT, Traits, Allocator>& string)
+{
+    return Buffer { (void*)string.data(), string.size() * sizeof(CharT) };
+};
 
-	}
+template <typename T, std::size_t N>
+Buffer make_buffer(const T (&data)[N])
+{
+    return Buffer { data, N * sizeof(T) };
+}
+
+template <typename T>
+Buffer make_buffer(T* data, std::size_t size)
+{
+    return Buffer { reinterpret_cast<void*>(data), size };
+}
 
 }
 
+}
 
-#endif
\ No newline at end of file
+#endif /* BASYX_ABSTRACTION_NET_BUFFER_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/net/Socket.h b/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/net/Socket.h
index 70826f8..00b6ac9 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/net/Socket.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/net/Socket.h
@@ -1,12 +1,12 @@
 /*
- * Socket.h
- *
- *  Created on: 05.02.2018
- *      Author: psota
- */
+* Socket.h
+*
+*  Created on: 05.02.2018
+*      Author: psota
+*/
 
-#ifndef ABSTRACTION_NET_SOCKET_H_
-#define ABSTRACTION_NET_SOCKET_H_
+#ifndef BASYX_ABSTRACTION_NET_SOCKET_H
+#define BASYX_ABSTRACTION_NET_SOCKET_H
 
 #include <BaSyx/abstraction/impl/socket_impl.h>
 
@@ -17,121 +17,112 @@
 #include <string>
 
 namespace basyx {
-	namespace net {
-		namespace tcp {
+namespace net {
+namespace tcp {
 
-			template<typename socket_impl>
-			class basic_socket
-			{
-			private:
-				basyx::log log;
-				std::unique_ptr<socket_impl> socket;
+template <typename socket_impl>
+class basic_socket {
+private:
+    basyx::log log;
+    std::unique_ptr<socket_impl> socket;
 
-				basic_socket<socket_impl> & _move_socket(basic_socket<socket_impl> && other)
-				{
-					// close current socket and assign new one
-					if (this->socket != nullptr)
-						this->socket->close();
+    basic_socket<socket_impl>& _move_socket(basic_socket<socket_impl>&& other)
+    {
+        // close current socket and assign new one
+        if (this->socket != nullptr)
+            this->socket->close();
 
-					this->socket = std::move(other.socket);
-					// other no longer represents a socket connection
-					other.socket.reset(nullptr);
-					return *this;
-				}
-			public:
-				basic_socket()
-					: socket{ nullptr }
-					, log{ "Socket" }
-				{
-				};
+        this->socket = std::move(other.socket);
+        // other no longer represents a socket connection
+        other.socket.reset(nullptr);
+        return *this;
+    }
 
-				basic_socket(std::unique_ptr<socket_impl> socket)
-					: socket{ std::forward<std::unique_ptr<socket_impl>>(socket) }
-					, log{"Socket"}
-				{
-				};
+public:
+    basic_socket()
+        : socket { nullptr }
+        , log { "Socket" } {};
 
-				~basic_socket()
-				{
-				};
+    basic_socket(std::unique_ptr<socket_impl> socket)
+        : socket { std::forward<std::unique_ptr<socket_impl>>(socket) }
+        , log { "Socket" } {};
 
-				// Delete copy-assignment and constructor, there should only ever be one Socket object representing a single connection
-				basic_socket<socket_impl> & operator=(basic_socket<socket_impl> & other) = delete;
-				basic_socket(basic_socket<socket_impl> & other) = delete;
+    ~basic_socket() {};
 
-				// Allow move-operations
-				basic_socket<socket_impl> & operator=(basic_socket<socket_impl> && other) { return _move_socket(std::forward<basic_socket<socket_impl>>(other)); };
-				basic_socket(basic_socket<socket_impl> && other) { _move_socket(std::forward<basic_socket<socket_impl>>(other)); };
+    // Delete copy-assignment and constructor, there should only ever be one Socket object representing a single connection
+    basic_socket<socket_impl>& operator=(basic_socket<socket_impl>& other) = delete;
+    basic_socket(basic_socket<socket_impl>& other) = delete;
 
-				template<typename Buffer>
-				std::size_t Send(Buffer && buffer)
-				{
-					if (socket == nullptr)
-						return 0;
+    // Allow move-operations
+    basic_socket<socket_impl>& operator=(basic_socket<socket_impl>&& other) { return _move_socket(std::forward<basic_socket<socket_impl>>(other)); };
+    basic_socket(basic_socket<socket_impl>&& other) { _move_socket(std::forward<basic_socket<socket_impl>>(other)); };
 
-					return socket->write(buffer.data(), buffer.size());
-				}
+    template <typename Buffer>
+    std::size_t Send(Buffer&& buffer)
+    {
+        if (socket == nullptr)
+            return 0;
 
-				template<typename MutableBuffer>
-				std::size_t Receive(MutableBuffer && buffer)
-				{
-					if (socket == nullptr)
-						return 0;
+        return socket->write(buffer.data(), buffer.size());
+    }
 
-					return socket->recv(buffer.data(), buffer.size(), 0);
-				}
+    template <typename MutableBuffer>
+    std::size_t Receive(MutableBuffer&& buffer)
+    {
+        if (socket == nullptr)
+            return 0;
 
-				static basic_socket<socket_impl> Connect(const std::string & address, int port)
-				{
-					return basic_socket<socket_impl>::Connect(address, std::to_string(port));
-				}
+        return socket->recv(buffer.data(), buffer.size(), 0);
+    }
 
-				static basic_socket<socket_impl> Connect(const std::string & address, const std::string & port)
-				{
-					//ToDo: Error handling
-					auto sock_impl = util::make_unique<socket_impl>();
-					auto result = sock_impl->connect(address, port);
+    static basic_socket<socket_impl> Connect(const std::string& address, int port)
+    {
+        return basic_socket<socket_impl>::Connect(address, std::to_string(port));
+    }
 
-					if (result != 0)
-						return basic_socket<socket_impl>{};
+    static basic_socket<socket_impl> Connect(const std::string& address, const std::string& port)
+    {
+        //ToDo: Error handling
+        auto sock_impl = util::make_unique<socket_impl>();
+        auto result = sock_impl->connect(address, port);
 
-					return basic_socket<socket_impl>{std::forward<std::unique_ptr<socket_impl>>(sock_impl)};
-				}
+        if (result != 0)
+            return basic_socket<socket_impl> {};
 
-				int GetErrorCode()
-				{
-					if (this->socket == nullptr)
-						return -1;
+        return basic_socket<socket_impl> { std::forward<std::unique_ptr<socket_impl>>(sock_impl) };
+    }
 
-					return this->socket->getErrorCode();
-				}
+    int GetErrorCode()
+    {
+        if (this->socket == nullptr)
+            return -1;
 
-				void Close()
-				{
-					if (this->socket != nullptr)
-					{
-						log.trace("Closing socket...");
+        return this->socket->getErrorCode();
+    }
 
-						//this->socket->shutdown(SHUTDOWN_RDWR);
-						this->socket->close();
-						this->socket.reset();
-					}
-				}
+    void Close()
+    {
+        if (this->socket != nullptr) {
+            log.trace("Closing socket...");
 
-				bool Healthy()
-				{
-					if (this->socket == nullptr)
-						return false;
+            //this->socket->shutdown(SHUTDOWN_RDWR);
+            this->socket->close();
+            this->socket.reset();
+        }
+    }
 
-					return true;
-				}
-			};
+    bool Healthy()
+    {
+        if (this->socket == nullptr)
+            return false;
 
+        return true;
+    }
+};
 
-
-			using Socket = basic_socket<basyx::net::impl::socket_impl>;
-		};
-	}
+using Socket = basic_socket<basyx::net::impl::socket_impl>;
+};
+}
 }
 
-#endif
+#endif /* BASYX_ABSTRACTION_NET_SOCKET_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/thread/Thread.h b/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/thread/Thread.h
index 07ec9d5..f1d1a08 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/thread/Thread.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/abstraction/thread/Thread.h
@@ -5,76 +5,77 @@
  *      Author: psota
  */
 
-#ifndef UTIL_THREAD_H
-#define UTIL_THREAD_H
+#ifndef BASYX_ABSTRACTION_THREAD_THREAD_H
+#define BASYX_ABSTRACTION_THREAD_THREAD_H
 
 #include <memory>
 
-#include <BaSyx/abstraction/impl/thread_launcher.h>
 #include <BaSyx/abstraction/impl/thread_impl.h>
+#include <BaSyx/abstraction/impl/thread_launcher.h>
 
 namespace basyx {
 
-	class thread
-	{
-	private:
-		std::unique_ptr<detail::thread_impl> thread_impl;
-	public:
-		// Creates empty Thread object
-		thread() noexcept : thread_impl{ nullptr } {};
+class thread {
+private:
+    std::unique_ptr<detail::thread_impl> thread_impl;
 
-		// Creates a Thread object with function f and parameters args and starts a new thread of execution
-		template<class Func, typename... Args>
-		explicit thread(Func && f, Args && ... args)
-			: thread_impl{ nullptr }
-		{
-			detail::Thread_Launcher<Func, Args...> launcher{ std::forward<Func>(f), std::forward<Args>(args)... };
-			launcher.Launch(thread_impl);
-		}
+public:
+    // Creates empty Thread object
+    thread() noexcept
+        : thread_impl { nullptr } {};
 
-		// Delete copy constructor, no two Thread objects should ever represent the same thread of exectuion
-		thread(const thread & Other) = delete;
+    // Creates a Thread object with function f and parameters args and starts a new thread of execution
+    template <class Func, typename... Args>
+    explicit thread(Func&& f, Args&&... args)
+        : thread_impl { nullptr }
+    {
+        detail::Thread_Launcher<Func, Args...> launcher { std::forward<Func>(f), std::forward<Args>(args)... };
+        launcher.Launch(thread_impl);
+    }
 
-		// Move constructor
-		thread(thread && other) noexcept
-		{
-			this->thread_impl = std::forward<std::unique_ptr<detail::thread_impl>>(other.thread_impl);
-			other.thread_impl.reset();
-		};
+    // Delete copy constructor, no two Thread objects should ever represent the same thread of exectuion
+    thread(const thread& Other) = delete;
 
-		// Move-assignment operator
-		thread & operator=(thread && other) noexcept
-		{
-			if (this->thread_impl != nullptr)
-				std::terminate();
+    // Move constructor
+    thread(thread&& other) noexcept
+    {
+        this->thread_impl = std::forward<std::unique_ptr<detail::thread_impl>>(other.thread_impl);
+        other.thread_impl.reset();
+    };
 
-			this->thread_impl = std::forward<std::unique_ptr<detail::thread_impl>>(other.thread_impl);
+    // Move-assignment operator
+    thread& operator=(thread&& other) noexcept
+    {
+        if (this->thread_impl != nullptr)
+            std::terminate();
 
-			return *this;
-		};
+        this->thread_impl = std::forward<std::unique_ptr<detail::thread_impl>>(other.thread_impl);
 
-		inline void join()
-		{
-			this->thread_impl->join();
-		};
+        return *this;
+    };
 
-		inline void detach()
-		{
-			this->thread_impl->detach();
-			this->thread_impl.reset();
-		};
+    inline void join()
+    {
+        this->thread_impl->join();
+    };
 
-		inline bool joinable()
-		{
-                    return false;
-		};
-	//Static utility functions
-	public:
-		static int currentThreadId()
-		{
-			return detail::thread_impl::getCurrentThreadId();
-		};
-	};
+    inline void detach()
+    {
+        this->thread_impl->detach();
+        this->thread_impl.reset();
+    };
+
+    inline bool joinable()
+    {
+        return false;
+    };
+    //Static utility functions
+public:
+    static int currentThreadId()
+    {
+        return detail::thread_impl::getCurrentThreadId();
+    };
+};
 }
 
-#endif
+#endif /* BASYX_ABSTRACTION_THREAD_THREAD_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/controlcomponent/enumerations/ControlComponentConstants.h b/sdks/c++/basys.sdk.cc/include/BaSyx/controlcomponent/enumerations/ControlComponentConstants.h
new file mode 100644
index 0000000..8df4194
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/controlcomponent/enumerations/ControlComponentConstants.h
@@ -0,0 +1,57 @@
+#ifndef BASYX_SUBMODEL_ENUM_ControlComponentConstants_H
+#define BASYX_SUBMODEL_ENUM_ControlComponentConstants_H
+
+#include <string>
+
+namespace basyx {
+namespace controlcomponent {
+
+enum class ControlComponentConstants {
+    status,
+    orderList,
+    LOCAL,
+    operations,
+    service,
+    clear,
+    stop,
+    abort,
+    unsuspend,
+    suspend,
+    unhold,
+    hold,
+    reset,
+    start,
+    simulation,
+    manual,
+    Auto,
+    semiauto,
+    priority,
+    occupy,
+    free,
+    bstate,
+    cmd,
+    localOverwriteFree,
+    localOverwrite,
+    prevError,
+    errorState,
+    workState,
+    opMode,
+    exState,
+    exMode,
+    lastOccupier,
+    occupier,
+    occupationState,
+};
+
+class ControlComponentConstants_
+{
+public:
+    static ControlComponentConstants from_string(const std::string & name);
+    static const char * to_string(ControlComponentConstants value);
+};
+
+
+}
+}
+
+#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/controlcomponent/enumerations/ExecutionMode.h b/sdks/c++/basys.sdk.cc/include/BaSyx/controlcomponent/enumerations/ExecutionMode.h
new file mode 100644
index 0000000..a035ef8
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/controlcomponent/enumerations/ExecutionMode.h
@@ -0,0 +1,20 @@
+#ifndef BASYX_CONTROLCOMPONENT_ENUM_EXECUTIONMODE_H
+#define BASYX_CONTROLCOMPONENT_ENUM_EXECUTIONMODE_H
+
+#include <string>
+
+namespace basyx {
+namespace controlcomponent {
+
+enum class ExecutionMode {
+    Auto = 1,
+    Semiauto = 2,
+    Manual = 3,
+    Reserved = 4,
+    Simulation = 5
+};
+
+}
+}
+
+#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/controlcomponent/enumerations/ExecutionOrder.h b/sdks/c++/basys.sdk.cc/include/BaSyx/controlcomponent/enumerations/ExecutionOrder.h
new file mode 100644
index 0000000..80cadb4
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/controlcomponent/enumerations/ExecutionOrder.h
@@ -0,0 +1,33 @@
+#ifndef BASYX_CONTROLCOMPONENT_ENUM_EXECUTIONORDER_H
+#define BASYX_CONTROLCOMPONENT_ENUM_EXECUTIONORDER_H
+
+#include <string>
+
+namespace basyx {
+namespace controlcomponent {
+
+enum class ExecutionOrder {
+    start,
+    complete,
+    reset,
+    hold,
+    unhold,
+    suspend,
+    unsuspend,
+    clear,
+    stop,
+    abort,
+};
+
+class ExecutionOrder_
+{
+public:
+    static ExecutionOrder from_string(const std::string & name);
+    static const char * to_string(ExecutionOrder value);
+};
+
+
+}
+}
+
+#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/controlcomponent/enumerations/ExecutionState.h b/sdks/c++/basys.sdk.cc/include/BaSyx/controlcomponent/enumerations/ExecutionState.h
new file mode 100644
index 0000000..f5ef17f
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/controlcomponent/enumerations/ExecutionState.h
@@ -0,0 +1,40 @@
+#ifndef BASYX_CONTROLCOMPONENT_ENUM_EXECUTIONSTATE_H
+#define BASYX_CONTROLCOMPONENT_ENUM_EXECUTIONSTATE_H
+
+#include <string>
+
+namespace basyx {
+namespace controlcomponent {
+
+enum class ExecutionState {
+    idle,
+    starting,
+    execute,
+    completing,
+    complete,
+    resetting,
+    holding,
+    held,
+    unholding,
+    suspending,
+    suspended,
+    unsuspending,
+    stopping,
+    stopped,
+    aborting,
+    aborted,
+    clearing,
+};
+
+class ExecutionState_
+{
+public:
+    static ExecutionState from_string(const std::string & name);
+    static const char * to_string(ExecutionState value);
+};
+
+
+}
+}
+
+#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/controlcomponent/enumerations/OccupationState.h b/sdks/c++/basys.sdk.cc/include/BaSyx/controlcomponent/enumerations/OccupationState.h
new file mode 100644
index 0000000..e1db83a
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/controlcomponent/enumerations/OccupationState.h
@@ -0,0 +1,17 @@
+#ifndef BASYX_CONTROLCOMPONENT_ENUM_OCCUPATIONSTATE_H
+#define BASYX_CONTROLCOMPONENT_ENUM_OCCUPATIONSTATE_H
+
+namespace basyx {
+namespace controlcomponent {
+
+enum class OccupationState {
+    free = 0,
+    occupied = 1,
+    priority = 2,
+    local = 3
+};
+
+}
+}
+
+#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/controlcomponent/interfaces/IControlComponent.h b/sdks/c++/basys.sdk.cc/include/BaSyx/controlcomponent/interfaces/IControlComponent.h
new file mode 100644
index 0000000..c05e95a
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/controlcomponent/interfaces/IControlComponent.h
@@ -0,0 +1,184 @@
+#ifndef BASYX_CONTROLCOMPONENT_ICONTROLCOMPONENT_H
+#define BASYX_CONTROLCOMPONENT_ICONTROLCOMPONENT_H
+
+#include <string>
+#include <vector>
+
+#include <BaSyx/shared/object.h>
+
+#include <BaSyx/controlcomponent/interfaces/IControlComponentChangeListener.h>
+
+#include <BaSyx/controlcomponent/enumerations/OccupationState.h>
+#include <BaSyx/controlcomponent/enumerations/ExecutionMode.h>
+#include <BaSyx/controlcomponent/enumerations/ExecutionState.h>
+
+/**
+ * BaSys 4.0 control component interface. This is a VAB object that cannot be serialized.
+ */
+namespace basyx {
+namespace controlcomponent {
+
+class IControlComponent
+{
+public:
+
+  /**
+   * Add ControlComponentChangeListener
+   */
+  virtual void addControlComponentChangeListener(const std::shared_ptr<IControlComponentChangeListener> listener) = 0;
+
+  /**
+   * Remove ControlComponentChangeListener
+   */
+  virtual void removeControlComponentChangeListener(const std::shared_ptr<IControlComponentChangeListener> listener) = 0;
+
+  /**
+   * Get "operations" map
+   */
+  virtual const basyx::object getServiceOperationMap() = 0;
+
+  /**
+   * Finish current execution state (execute 'SC' order). This only works in transition states
+   */
+  virtual void finishState() = 0;
+
+  /**
+   * Get order list
+   */
+  virtual const std::vector<std::string> & getOrderList() = 0;
+
+  /**
+   * Add order to order list
+   */
+  virtual void addOrder(const std::string &newOrder) = 0;
+
+  /**
+   * Clear order list
+   */
+  virtual void clearOrder() = 0;
+
+  /**
+   * Get occupation state
+   */
+  virtual OccupationState getOccupationState() = 0;
+
+  /**
+   * Set occupation state
+   */
+  virtual void setOccupationState(const OccupationState &occSt) = 0;
+
+  /**
+   * Get occupier ID
+   */
+  virtual std::string getOccupierID() = 0;
+
+  /**
+   * Set occupier ID
+   */
+  virtual void setOccupierID(const std::string &occId) = 0;
+
+  /**
+   * Get last occupier ID
+   */
+  virtual std::string getLastOccupierID() = 0;
+
+  /**
+   * Set last occupier ID
+   */
+  virtual void setLastOccupierID(const std::string &occId) = 0;
+
+  /**
+   * Get execution mode
+   */
+  virtual ExecutionMode getExecutionMode() = 0;
+
+  /**
+   * Set execution mode
+   */
+  virtual void setExecutionMode(const ExecutionMode &exMode) = 0;
+
+  /**
+   * Get execution state
+   */
+  virtual ExecutionState getExecutionState() = 0;
+
+  /**
+   * Set execution state
+   */
+  virtual void setExecutionState(const ExecutionState &newSt) = 0;
+
+  /**
+   * Get operation mode
+   */
+  virtual std::string getOperationMode() = 0;
+
+  /**
+   * Set operation mode
+   */
+  virtual void setOperationMode(const std::string &opMode) = 0;
+
+  /**
+   * Get work state
+   */
+  virtual std::string getWorkState() = 0;
+
+  /**
+   * Set work state
+   */
+  virtual void setWorkState(const std::string &workState) = 0;
+
+  /**
+   * Get error state
+   */
+  virtual std::string getErrorState() = 0;
+
+  /**
+   * Set error state
+   */
+  virtual void setErrorState(const std::string &errorState) = 0;
+
+  /**
+   * Get last error state
+   */
+  virtual std::string getLastErrorState() = 0;
+
+  /**
+   * Set last error state
+   */
+  virtual void setLastErrorState(const std::string &lastErrorState) = 0;
+
+  /**
+   * Get last command
+   */
+  virtual std::string getCommand() = 0;
+
+  /**
+   * Set command
+   */
+  virtual void setCommand(const std::string &cmd) = 0;
+
+  /**
+   * Get local overwrite variable
+   */
+  virtual std::string getLocalOverwrite() = 0;
+
+  /**
+   * Set local overwrite variable
+   */
+  virtual void setLocalOverwrite(const std::string &cmd) = 0;
+
+  /**
+   * Get local overwrite free variable
+   */
+  virtual std::string getLocalOverwriteFree() = 0;
+
+  /**
+   * Set local overwrite free variable
+   */
+  virtual void setLocalOverwriteFree(const std::string &cmd) = 0;
+};
+
+}
+}
+
+#endif /* BASYX_CONTROLCOMPOMPONENT_ICONTROLCOMPONENT_H */
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/controlcomponent/interfaces/IControlComponentChangeListener.h b/sdks/c++/basys.sdk.cc/include/BaSyx/controlcomponent/interfaces/IControlComponentChangeListener.h
new file mode 100644
index 0000000..98729e5
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/controlcomponent/interfaces/IControlComponentChangeListener.h
@@ -0,0 +1,90 @@
+#ifndef BASYX_CONTROLCOMPONENT_ICONTROLCOMPONENTCHANGELISTENER_H
+#define BASYX_CONTROLCOMPONENT_ICONTROLCOMPONENTCHANGELISTENER_H
+
+#include <BaSyx/shared/object.h>
+#include <BaSyx/controlcomponent/enumerations/OccupationState.h>
+#include <BaSyx/controlcomponent/enumerations/ExecutionState.h>
+#include <BaSyx/controlcomponent/enumerations/ExecutionMode.h>
+
+namespace basyx {
+namespace controlcomponent {
+
+/**
+ * Receive change events from control components.
+ */
+class IControlComponentChangeListener
+{
+public:
+  virtual ~IControlComponentChangeListener() = 0;
+
+  /**
+   * Indicate change of a variable
+   */
+  virtual void onVariableChange(const std::string & varName, object newValue) = 0;
+
+
+  /**
+   * Indicate new occupier
+   */
+  virtual void onNewOccupier(const std::string & occupierId) = 0;
+
+
+  /**
+   * Indicate new occupation state
+   */
+  virtual void onNewOccupationState(OccupationState state) = 0;
+
+
+  /**
+   * Indicate a change of last occupier.
+   */
+  virtual void onLastOccupier(const std::string & lastOccupierId) = 0;
+
+
+  /**
+   * Indicate an execution mode change
+   */
+  virtual void onChangedExecutionMode(ExecutionMode newExecutionMode) = 0;
+
+
+  /**
+   * Indicate an execution state change
+   */
+  virtual void onChangedExecutionState(ExecutionState newExecutionState) = 0;
+
+
+  /**
+   * Indicate an operation mode change
+   */
+  virtual void onChangedOperationMode(const std::string & newOperationMode) = 0;
+
+
+  /**
+   * Indicate an work state change
+   */
+  virtual void onChangedWorkState(const std::string & newWorkState) = 0;
+
+
+  /**
+   * Indicate an error state change
+   */
+  virtual void onChangedErrorState(const std::string & newWorkState) = 0;
+
+
+  /**
+   * Indicate an previous error state change.
+   */
+  virtual void onChangedPrevError(const std::string & newWorkState) = 0;
+
+  /**
+   * Generates a unique ID to identify ControlComponentChangeListener
+   */
+  virtual int getUniqueID() = 0;
+};
+
+inline IControlComponentChangeListener::~IControlComponentChangeListener() = default;
+
+}
+}
+
+#endif //BASYX_API_V2_SDK_ICONTROLCOMPONENTCHANGELISTENER_H
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/controlcomponent/map/ControlComponent.h b/sdks/c++/basys.sdk.cc/include/BaSyx/controlcomponent/map/ControlComponent.h
new file mode 100644
index 0000000..4a6879b
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/controlcomponent/map/ControlComponent.h
@@ -0,0 +1,111 @@
+#ifndef BASYX_CONTROLCOMPONENT_MAP_CONTROLCOMPONENT_H
+#define BASYX_CONTROLCOMPONENT_MAP_CONTROLCOMPONENT_H
+
+#include <BaSyx/controlcomponent/interfaces/IControlComponent.h>
+
+#include <BaSyx/vab/ElementMap.h>
+#include <BaSyx/controlcomponent/enumerations/ControlComponentConstants.h>
+#include <BaSyx/controlcomponent/enumerations/ExecutionOrder.h>
+
+namespace basyx {
+namespace controlcomponent {
+namespace map {
+
+class ControlComponent : public IControlComponent, public vab::ElementMap
+{
+private:
+  std::map<int, std::shared_ptr<IControlComponentChangeListener>> componentChangeListeners;
+  std::string savedOccupierId;
+  basyx::object status_map, operations;
+
+public:
+  ControlComponent();
+
+  virtual void addControlComponentChangeListener(const std::shared_ptr<IControlComponentChangeListener> listener) override;
+
+  virtual void removeControlComponentChangeListener(const std::shared_ptr<IControlComponentChangeListener> listener) override;
+
+  const basyx::object getServiceOperationMap();
+
+  void put(const std::string &key, basyx::object value);
+
+  virtual void finishState() override;
+
+  virtual const std::vector<std::string> & getOrderList() override;
+
+  virtual void addOrder(const std::string &newOrder) override;
+
+  virtual void clearOrder() override;
+
+  virtual OccupationState getOccupationState() override;
+
+  virtual void setOccupationState(const OccupationState &occState) override;
+
+  virtual std::string getOccupierID() override;
+
+  virtual void setOccupierID(const std::string &occId) override;
+
+  virtual std::string getLastOccupierID() override;
+
+  virtual void setLastOccupierID(const std::string &occId) override;
+
+  virtual ExecutionMode getExecutionMode() override;
+
+  virtual void setExecutionMode(const ExecutionMode &exMode) override;
+
+  virtual ExecutionState getExecutionState() override;
+
+  virtual void setExecutionState(const ExecutionState &newSt) override;
+
+  virtual std::string getOperationMode() override;
+
+  virtual void setOperationMode(const std::string &opMode) override;
+
+  virtual std::string getWorkState() override;
+
+  virtual void setWorkState(const std::string &workState) override;
+
+  virtual std::string getErrorState() override;
+
+  virtual void setErrorState(const std::string &errorState) override;
+
+  virtual std::string getLastErrorState() override;
+
+  virtual void setLastErrorState(const std::string &lastErrorState) override;
+
+  virtual std::string getCommand() override;
+
+  virtual void setCommand(const std::string &cmd) override;
+
+  virtual std::string getLocalOverwrite() override;
+
+  virtual void setLocalOverwrite(const std::string &cmd) override;
+
+  virtual std::string getLocalOverwriteFree() override;
+
+  virtual void setLocalOverwriteFree(const std::string &cmd) override;
+
+private:
+  void changeExecutionState(const ExecutionOrder &);
+
+  void invokeLocalOverwrite();
+
+  void clearLocalOverwrite();
+
+  void freeControlComponent(const std::string &);
+
+  void occupyControlComponent(const std::string &occupier);
+
+  void priorityOccupation(const std::string &occupier);
+
+  object init_service_operations();
+
+  template<typename T> void insert_status(const basyx::controlcomponent::ControlComponentConstants &, T status);
+
+  template<typename T> T get_status(const basyx::controlcomponent::ControlComponentConstants &);
+};
+
+}
+}
+}
+#endif //BASYX_CONTROLCOMPONENT_CONTROLCOMPONENT_H
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/controlcomponent/simple/ControlComponent.h b/sdks/c++/basys.sdk.cc/include/BaSyx/controlcomponent/simple/ControlComponent.h
new file mode 100644
index 0000000..5614968
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/controlcomponent/simple/ControlComponent.h
@@ -0,0 +1,92 @@
+#ifndef BASYX_CONTROLCOMPONENT_SIMPLE_CONTROLCOMPONENT_H
+#define BASYX_CONTROLCOMPONENT_SIMPLE_CONTROLCOMPONENT_H
+
+#include <BaSyx/controlcomponent/interfaces/IControlComponent.h>
+
+#include <BaSyx/controlcomponent/enumerations/ControlComponentConstants.h>
+#include <BaSyx/controlcomponent/enumerations/ExecutionOrder.h>
+
+namespace basyx {
+namespace controlcomponent {
+namespace simple {
+
+class ControlComponent : public IControlComponent
+{
+private:
+  std::map<int, std::shared_ptr<IControlComponentChangeListener>> componentChangeListeners;
+  std::string savedOccupierId;
+  std::string occupier, lastOccupier, opMode, workState, errorState, prevError, cmd, localOverwrite, localOverwriteFree;
+  ExecutionState exState;
+  OccupationState occupationState;
+  ExecutionMode exMode;
+
+  std::string operations;
+  basyx::object service_operations;
+  std::vector<std::string> orderList;
+
+public:
+  ControlComponent();
+
+  virtual void addControlComponentChangeListener(const std::shared_ptr<IControlComponentChangeListener> listener) override;
+  virtual void removeControlComponentChangeListener(const std::shared_ptr<IControlComponentChangeListener> listener) override;
+
+  const basyx::object getServiceOperationMap();
+
+  virtual void finishState() override;
+  virtual const std::vector<std::string> & getOrderList() override;
+
+  virtual void addOrder(const std::string &newOrder) override;
+  virtual void clearOrder() override;
+
+  virtual OccupationState getOccupationState() override;
+  virtual void setOccupationState(const OccupationState &occState) override;
+
+  virtual std::string getOccupierID() override;
+  virtual void setOccupierID(const std::string &occId) override;
+
+  virtual std::string getLastOccupierID() override;
+  virtual void setLastOccupierID(const std::string &occId) override;
+
+  virtual ExecutionMode getExecutionMode() override;
+  virtual void setExecutionMode(const ExecutionMode &exMode) override;
+
+  virtual ExecutionState getExecutionState() override;
+  virtual void setExecutionState(const ExecutionState &newSt) override;
+
+  virtual std::string getOperationMode() override;
+  virtual void setOperationMode(const std::string &opMode) override;
+
+  virtual std::string getWorkState() override;
+  virtual void setWorkState(const std::string &workState) override;
+
+  virtual std::string getErrorState() override;
+  virtual void setErrorState(const std::string &errorState) override;
+
+  virtual std::string getLastErrorState() override;
+  virtual void setLastErrorState(const std::string &lastErrorState) override;
+
+  virtual std::string getCommand() override;
+  virtual void setCommand(const std::string &cmd) override;
+
+  virtual std::string getLocalOverwrite() override;
+  virtual void setLocalOverwrite(const std::string &cmd) override;
+
+  virtual std::string getLocalOverwriteFree() override;
+  virtual void setLocalOverwriteFree(const std::string &cmd) override;
+
+private:
+  void changeExecutionState(const ExecutionOrder &);
+  void invokeLocalOverwrite();
+  void clearLocalOverwrite();
+  void freeControlComponent(const std::string &);
+  void occupyControlComponent(const std::string &occupier);
+  void priorityOccupation(const std::string &occupier);
+  void init_service_operations();
+
+  template<typename T> void notify_change_listeners_on_variable_change(const basyx::controlcomponent::ControlComponentConstants &status_key, T status);
+};
+
+}
+}
+}
+#endif //BASYX_CONTROLCOMPONENT_CONTROLCOMPONENT_H
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/log/log.h b/sdks/c++/basys.sdk.cc/include/BaSyx/log/log.h
index cb24202..627b459 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/log/log.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/log/log.h
@@ -1,115 +1,118 @@
-#ifndef LOGGING_LOG_H_
-#define LOGGING_LOG_H_
+#ifndef BASYX_LOG_LOG_H
+#define BASYX_LOG_LOG_H
 
 #include <iostream>
 
 #include <fmt/format.h>
 
 namespace basyx {
-	class log {
-	public:
-		enum class Level
-		{
-			Debug = 0,
-			Trace = 1,
-			Info = 2,
-			Warn = 3,
-			Error = 4,
-			Critical = 5
-		};
-	public:
-		explicit log(const std::string& sourceName)
-			: sourceName{ sourceName }
-		{
-		}
 
-		explicit log()
-			: sourceName{ "" } {};
+class log {
+public:
+    enum class Level {
+        Debug = 0,
+        Trace = 1,
+        Info = 2,
+        Warn = 3,
+        Error = 4,
+        Critical = 5
+    };
 
-	private:
-		const char * printLevel(Level level);
-	private:
-		static Level logLevel;
-	public:
-		static void setLogLevel(Level level)
-		{
-			logLevel = level;
-		};
-	private:
-		std::string sourceName;
+public:
+    explicit log(const std::string& sourceName)
+        : sourceName { sourceName }
+    {
+    }
 
-		std::string timestamp();
+    explicit log()
+        : sourceName { "" } {};
 
-		template<typename... Args>
-		std::string buildMessage(const std::string & format, Level level, Args && ... args)
-		{
-			auto message = fmt::format("[{}] [{}] [{}] {}", timestamp(), printLevel(level), sourceName, format);
-			return fmt::format(message, std::forward<Args>(args)...);
-		};
+private:
+    const char* printLevel(Level level);
 
-		//template<typename T>
-		//inline T && normalize(T && t)
-		//{
-		//	return std::forward<T>(t);
-		//}
+private:
+    static Level logLevel;
 
-		//inline const char * normalize(const std::string & s)
-		//{
-		//	return s.c_str();
-		//}
+public:
+    static void setLogLevel(Level level)
+    {
+        logLevel = level;
+    };
 
+private:
+    std::string sourceName;
 
-		template<typename... Args>
-		inline void log_message(Level level, const std::string & msg, Args && ... args)
-		{
-			if (level >= logLevel)
-				std::cout << buildMessage(msg, level, std::forward<Args>(args)...) << std::endl;
-		};
+    std::string timestamp();
 
-	public:
-		template <typename... Args>
-		inline void trace(const std::string& msg, Args&&... args)
-		{
-			log_message(Level::Trace, msg, std::forward<Args>(args)...);
-		}
+    template <typename... Args>
+    std::string buildMessage(const std::string& format, Level level, Args&&... args)
+    {
+        auto message = fmt::format("[{}] [{}] [{}] {}", timestamp(), printLevel(level), sourceName, format);
+        return fmt::format(message, std::forward<Args>(args)...);
+    };
 
-		template <typename... Args>
-		inline void debug(const std::string& msg, Args&&... args)
-		{
-			log_message(Level::Debug, msg, std::forward<Args>(args)...);
-		}
+    //template<typename T>
+    //inline T && normalize(T && t)
+    //{
+    //	return std::forward<T>(t);
+    //}
 
-		template <typename... Args>
-		inline void info(const std::string& msg, Args&&... args)
-		{
-			log_message(Level::Info, msg, std::forward<Args>(args)...);
-		}
+    //inline const char * normalize(const std::string & s)
+    //{
+    //	return s.c_str();
+    //}
 
-		template <typename... Args>
-		inline void warn(const std::string& msg, Args&&... args)
-		{
-			log_message(Level::Warn, msg, std::forward<Args>(args)...);
-		}
+    template <typename... Args>
+    inline void log_message(Level level, const std::string& msg, Args&&... args)
+    {
+        if (level >= logLevel)
+            std::cout << buildMessage(msg, level, std::forward<Args>(args)...) << std::endl;
+    };
 
-		template <typename... Args>
-		inline void error(const std::string& msg, Args&&... args)
-		{
-			log_message(Level::Error, msg, std::forward<Args>(args)...);
-		}
+public:
+    template <typename... Args>
+    inline void trace(const std::string& msg, Args&&... args)
+    {
+        log_message(Level::Trace, msg, std::forward<Args>(args)...);
+    }
 
-		template <typename... Args>
-		inline void crit(const std::string& msg, Args&&... args)
-		{
-			log_message(Level::Critical, msg, std::forward<Args>(args)...);
-		}
+    template <typename... Args>
+    inline void debug(const std::string& msg, Args&&... args)
+    {
+        log_message(Level::Debug, msg, std::forward<Args>(args)...);
+    }
 
-	// static logging functions
-	public:
-		inline static log topic(const std::string & topic)
-		{
-			return log(topic);
-		};
-	};
+    template <typename... Args>
+    inline void info(const std::string& msg, Args&&... args)
+    {
+        log_message(Level::Info, msg, std::forward<Args>(args)...);
+    }
+
+    template <typename... Args>
+    inline void warn(const std::string& msg, Args&&... args)
+    {
+        log_message(Level::Warn, msg, std::forward<Args>(args)...);
+    }
+
+    template <typename... Args>
+    inline void error(const std::string& msg, Args&&... args)
+    {
+        log_message(Level::Error, msg, std::forward<Args>(args)...);
+    }
+
+    template <typename... Args>
+    inline void crit(const std::string& msg, Args&&... args)
+    {
+        log_message(Level::Critical, msg, std::forward<Args>(args)...);
+    }
+
+    // static logging functions
+public:
+    inline static log topic(const std::string& topic)
+    {
+        return log(topic);
+    };
+};
 };
 
-#endif
+#endif /* BASYX_LOG_LOG_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/server/BaSyxNativeProvider.h b/sdks/c++/basys.sdk.cc/include/BaSyx/server/BaSyxNativeProvider.h
index 6f74321..057a92f 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/server/BaSyxNativeProvider.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/server/BaSyxNativeProvider.h
@@ -1,12 +1,12 @@
 /*
- * BaSyxNativeProvider.h
- *
- *  Created on: 14.08.2018
- *      Author: schnicke
- */
+* BaSyxNativeProvider.h
+*
+*  Created on: 14.08.2018
+*      Author: schnicke
+*/
 
-#ifndef VAB_VAB_PROVIDER_NATIVE_BASYXNATIVEPROVIDER_H
-#define VAB_VAB_PROVIDER_NATIVE_BASYXNATIVEPROVIDER_H
+#ifndef BASYX_SERVER_BASYXNATIVEPROVIDER_H
+#define BASYX_SERVER_BASYXNATIVEPROVIDER_H
 
 #include <BaSyx/shared/types.h>
 
@@ -21,135 +21,128 @@
 
 #include <asio.hpp>
 
-
 /**
- * Provies access based on the basyx native protocol
- */
+* Provies access based on the basyx native protocol
+*/
 
 namespace basyx {
 namespace vab {
 namespace provider {
 namespace native {
 
-	class NativeProvider {
-	private:
-		// Connection socket
-		asio::ip::tcp::socket & clientSocket;
+class NativeProvider {
+private:
+    // Connection socket
+    asio::ip::tcp::socket& clientSocket;
 
-		// Frame processor
-		frame::BaSyxNativeFrameProcessor * frameProcessor;
+    // Frame processor
+    frame::BaSyxNativeFrameProcessor* frameProcessor;
 
-		// Buffers
-		static constexpr std::size_t default_buffer_size = 4096;
-		std::array<char, default_buffer_size> recv_buffer;
-		std::array<char, default_buffer_size> send_buffer;
+    // Buffers
+    static constexpr std::size_t default_buffer_size = 8192;
+    std::array<char, default_buffer_size> recv_buffer;
+    std::array<char, default_buffer_size> send_buffer;
 
-		bool closed;
-		basyx::log log;
-	public:
-		NativeProvider(asio::ip::tcp::socket & clientSocket,
-			frame::BaSyxNativeFrameProcessor* frameProcessor)
-			: clientSocket(clientSocket)
-			, frameProcessor(frameProcessor)
-			, closed(false)
-			, log{ "NativeProvider" }
-		{
-		}
+    bool closed;
+    basyx::log log;
 
-		~NativeProvider()
-		{
-			// Connection no longer needed, close it
-			try
-			{
-				if (this->clientSocket.is_open())
-					this->clientSocket.close();
-			}
-			catch (std::exception & e)
-			{
-				log.warn("Exception in closing socket");
-			};
-		}
+public:
+    NativeProvider(asio::ip::tcp::socket& clientSocket,
+        frame::BaSyxNativeFrameProcessor* frameProcessor)
+        : clientSocket(clientSocket)
+        , frameProcessor(frameProcessor)
+        , closed(false)
+        , log { "NativeProvider" }
+    {
+    }
 
-		// Has to be called repeatedly
-		void update()
-		{
-			log.trace("Updating...");
-			if (!closed)
-			{
-				asio::error_code ec;
-				log.trace("Waiting for incoming message");
-				auto input_frame = recvFrame(ec);
+    ~NativeProvider()
+    {
+        // Connection no longer needed, close it
+        try {
+            if (this->clientSocket.is_open())
+                this->clientSocket.close();
+        } catch (std::exception& e) {
+            log.warn("Exception in closing socket: {}", e.what());
+        };
+    }
 
-				if(ec) {
-					log.info("Connection closed");
-					closed = true;
-				}
-				else {
-					log.trace("Received frame.");
-					log.info("Received: {}", input_frame.getFirstValue());
+    // Has to be called repeatedly
+    void update()
+    {
+        log.trace("Updating...");
+        if (!closed) {
+            asio::error_code ec;
+            log.trace("Waiting for incoming message");
+            auto input_frame = recvFrame(ec);
 
-					auto output_frame = frameProcessor->processInputFrame(input_frame);
+            if (ec) {
+                log.info("Connection closed");
+                closed = true;
+            } else {
+                log.trace("Received frame.");
+                log.info("Received: {}", input_frame.getFirstValue());
 
-					log.info("Sending reply.");
+                auto output_frame = frameProcessor->processInputFrame(input_frame);
 
-					auto bytes_sent = sendFrame(output_frame);
-					if (bytes_sent < 0) {
-						log.error("Sending failed: {}", "ERROR");
-						closed = true;
-					}
-				}
-			}
-		}
+                log.info("Sending reply.");
 
-		bool isClosed()
-		{
-			return closed;
-		}
+                auto bytes_sent = sendFrame(output_frame);
+                if (bytes_sent < 0) {
+                    log.error("Sending failed: {}", "ERROR");
+                    closed = true;
+                }
+            }
+        }
+    }
 
-		std::size_t sendData(char* data, std::size_t size)
-		{
-			log.debug("Sending {} bytes.", size);
-			std::size_t bytes_sent = this->clientSocket.send(asio::buffer(data, size));
-			log.debug("Sent {} bytes.", bytes_sent);
-			return bytes_sent;
-		};
+    bool isClosed()
+    {
+        return closed;
+    }
 
+    std::size_t sendData(char* data, std::size_t size)
+    {
+        log.debug("Sending {} bytes.", size);
+        std::size_t bytes_sent = this->clientSocket.send(asio::buffer(data, size));
+        log.debug("Sent {} bytes.", bytes_sent);
+        return bytes_sent;
+    };
 
-		std::size_t receiveData(char* data, asio::error_code & ec)
-		{
-			std::size_t bytes_read = this->clientSocket.receive(asio::buffer(recv_buffer.data(), recv_buffer.size()), 0, ec);
-			log.debug("Received {} bytes.", bytes_read);
-			return bytes_read;
-		};
+    std::size_t receiveData(char* data, asio::error_code& ec)
+    {
+        std::size_t bytes_read = this->clientSocket.receive(asio::buffer(recv_buffer.data(), recv_buffer.size()), 0, ec);
+        log.debug("Received {} bytes.", bytes_read);
+        return bytes_read;
+    };
 
-		std::size_t sendFrame(const connector::native::Frame & frame)
-		{
-			connector::native::Frame::write_to_buffer(
-				basyx::net::make_buffer(
-					send_buffer.data() + BASYX_FRAMESIZE_SIZE, default_buffer_size - BASYX_FRAMESIZE_SIZE),
-				frame);
+    std::size_t sendFrame(const connector::native::Frame& frame)
+    {
+        connector::native::Frame::write_to_buffer(
+            basyx::net::make_buffer(
+                send_buffer.data() + BASYX_FRAMESIZE_SIZE, default_buffer_size - BASYX_FRAMESIZE_SIZE),
+            frame);
 
-			auto size_field = reinterpret_cast<uint32_t*>(&send_buffer[0]);
-			*size_field = frame.size();
+        auto size_field = reinterpret_cast<uint32_t*>(&send_buffer[0]);
+        *size_field = static_cast<uint32_t>(frame.size());
 
-			return sendData(send_buffer.data(), frame.size() + BASYX_FRAMESIZE_SIZE);
-		};
+        return sendData(send_buffer.data(), frame.size() + BASYX_FRAMESIZE_SIZE);
+    };
 
-		connector::native::Frame recvFrame(asio::error_code & ec)
-		{
-			this->receiveData(recv_buffer.data(), ec);
-			auto size = *reinterpret_cast<uint32_t*>(recv_buffer.data());
-			auto frame = connector::native::Frame::read_from_buffer(
-				basyx::net::make_buffer(this->recv_buffer.data() + BASYX_FRAMESIZE_SIZE, size - BASYX_FRAMESIZE_SIZE)
-			);
+    connector::native::Frame recvFrame(asio::error_code& ec)
+    {
+        this->receiveData(recv_buffer.data(), ec);
+        auto size = *reinterpret_cast<uint32_t*>(recv_buffer.data());
+        auto frame = connector::native::Frame::read_from_buffer(
+            basyx::net::make_buffer(this->recv_buffer.data() + BASYX_FRAMESIZE_SIZE, size - BASYX_FRAMESIZE_SIZE));
 
-			return frame;
-		};
-	};
+        return frame;
+    };
+};
 
 };
 };
 };
 };
 
-#endif /* VAB_VAB_PROVIDER_NATIVE_BASYXNATIVEPROVIDER_H */
+#endif /* BASYX_SERVER_BASYXNATIVEPROVIDER_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/server/TCPSelectServer.h b/sdks/c++/basys.sdk.cc/include/BaSyx/server/TCPSelectServer.h
index 5ef3c75..6dfef78 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/server/TCPSelectServer.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/server/TCPSelectServer.h
@@ -4,8 +4,8 @@
  *      Author: wendel
  */
 
-#ifndef BASYX_SERVER_BASYXTCPSELECTSERVER_H_
-#define BASYX_SERVER_BASYXTCPSELECTSERVER_H_
+#ifndef BASYX_SERVER_TCPSELECTSERVER_H
+#define BASYX_SERVER_TCPSELECTSERVER_H
 
 #include <BaSyx/vab/core/IModelProvider.h>
 #include <BaSyx/vab/provider/native/frame/BaSyxNativeFrameProcessor.h>
@@ -115,4 +115,4 @@
 }
 }
 
-#endif
+#endif /* BASYX_SERVER_TCPSELECTSERVER_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/server/TCPServer.h b/sdks/c++/basys.sdk.cc/include/BaSyx/server/TCPServer.h
index 98e0f22..0e50193 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/server/TCPServer.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/server/TCPServer.h
@@ -1,5 +1,5 @@
-#ifndef VAB_VAB_PROVIDER_NATIVE_BASYXTCPSERVER_2_H
-#define VAB_VAB_PROVIDER_NATIVE_BASYXTCPSERVER_2_H
+#ifndef BASYX_SERVER_TCPSERVER_H
+#define BASYX_SERVER_TCPSERVER_H
 
 #include <atomic>
 #include <iostream>
@@ -15,174 +15,163 @@
 namespace basyx {
 namespace server {
 
-	template <typename Backend>
-	class TCPServer {
-	public:
-		using socket_ptr_t = std::unique_ptr<asio::ip::tcp::socket>;
-	private:
-		Backend * backend;
+template <typename Backend>
+class TCPServer {
+public:
+    using socket_ptr_t = std::unique_ptr<asio::ip::tcp::socket>;
 
-		asio::io_context io_context;
-		asio::ip::tcp::acceptor acceptor;
+private:
+    Backend* backend;
 
-		std::vector<std::thread> threads;
-		std::vector<socket_ptr_t> sockets;
+    asio::io_context io_context;
+    asio::ip::tcp::acceptor acceptor;
 
-		bool closed;
-		std::atomic_bool running;
+    std::vector<std::thread> threads;
+    std::vector<socket_ptr_t> sockets;
 
-		basyx::log log;
+    bool closed;
+    std::atomic_bool running;
 
-	public:
-		TCPServer(Backend * backend, int port)
-			: backend{ backend }
-			, running{ true }
-			, io_context{ 0 }
-			, acceptor{ io_context, asio::ip::tcp::endpoint(asio::ip::tcp::v4(), port) }
-			, log{ "TCPServer" }
-		{
-			// ToDo: Check health of acceptor
-			log.info("Starting server on port {}", port);
-//			acceptor.listen();
-			start_accept();
-		}
+    basyx::log log;
 
-		void run()
-		{
-			this->io_context.run();
-		};
+public:
+    TCPServer(Backend* backend, int port)
+        : backend { backend }
+        , running { false }
+        , io_context { 1 }
+        , acceptor { io_context, asio::ip::tcp::endpoint(asio::ip::tcp::v4(), port) }
+        , log { "TCPServer" }
+    {
+        // ToDo: Check health of acceptor
+        log.info("Starting server on port {}", port);
+        acceptor.listen();
+    }
 
-		void stop()
-		{
-			this->io_context.stop();
-		};
+    void run()
+    {
+		start_accept();
+		this->running.store(true);
+		this->io_context.run();
+    };
 
-		void start_accept()
-		{
-			asio::error_code ec;
-			auto client_socket = util::make_unique<asio::ip::tcp::socket>(io_context);
-			//this->acceptor.accept(*client_socket.get(), ec);
+    void stop()
+    {
+        this->io_context.stop();
+    };
 
-			//auto error = WSAGetLastError();
+    void start_accept()
+    {
+        asio::error_code ec;
+        auto client_socket = util::make_unique<asio::ip::tcp::socket>(io_context);
 
-			//if (!client_socket->is_open()) {
-			//	log.warn("Incoming connection failed");
-			//	return;
-			//}
-			sockets.emplace_back(std::move(client_socket));
+		sockets.emplace_back(std::move(client_socket));
 
-			acceptor.async_accept(*sockets.back(),
-				std::bind(&TCPServer::handle_accept, this,
-					std::placeholders::_1));
-		};
+        acceptor.async_accept(*sockets.back(),
+            std::bind(&TCPServer::handle_accept, this,
+                std::placeholders::_1));
+    };
 
-		void handle_accept(
-			const asio::error_code& error)
-		{
-			if (!error)
-			{
-				log.info("Incoming new connection");
+    void handle_accept(
+        const asio::error_code& error)
+    {
+        if (!error) {
+            log.info("Incoming new connection");
 
-				std::thread handlerThread{ &TCPServer<Backend>::processConnection, this, std::ref(*sockets.back()) };
-				threads.emplace_back(std::move(handlerThread));
-			}
-			else
-			{
-				sockets.pop_back();
-			}
+            std::thread handlerThread { &TCPServer<Backend>::processConnection, this, std::ref(*sockets.back()) };
+            threads.emplace_back(std::move(handlerThread));
+        } else {
+            sockets.pop_back();
+        }
 
-			start_accept();
-		};
+        start_accept();
+    };
 
-		void Close()
-		{
-			log.trace("Closing...");
+    void Close()
+    {
+        log.trace("Closing...");
 
-			if (!isRunning())
-				return;
+        if (!isRunning())
+            return;
 
-			running.store(false);
-			this->stop();
+        running.store(false);
+        this->stop();
 
-			//// Close the acceptor socket
-			//log.trace("Closing Acceptor...");
-			//acceptor.close();
+        //// Close the acceptor socket
+        //log.trace("Closing Acceptor...");
+        //acceptor.close();
 
-			// Close all accepted connections
-			// This will bring all open connection threads to a finish
-			log.trace("Closing open connections...");
-			for (auto& socket : sockets)
-			{
-				try {
-					if (socket->is_open())
-						socket->close();
-				}
-				catch (std::exception & e)
-				{
-					log.warn("Socket closed unexpectedly.");
-				}
-			};
+        // Close all accepted connections
+        // This will bring all open connection threads to a finish
+        log.trace("Closing open connections...");
+        for (auto& socket : sockets) {
+            try {
+                if (socket->is_open())
+                    socket->close();
+            } catch (std::exception& e) {
+                log.warn("Socket closed unexpectedly: {}", e.what());
+            }
+        };
 
-			// Wait for all threads to finish
-			for (auto& thread : threads)
-				thread.join();
+        // Wait for all threads to finish
+        for (auto& thread : threads)
+            thread.join();
 
-			// ToDo: Check for errors during cleanup
-		}
+        // ToDo: Check for errors during cleanup
+    }
 
-		~TCPServer()
-		{
-			this->Close();
-		}
+    ~TCPServer()
+    {
+        this->Close();
+    }
 
-		/**
-		* Has to be called periodically
-		*/
-		void update()
-		{
-			if (isRunning()) {
-				log.info("Accepting new connections.");
+    /**
+    * Has to be called periodically
+    */
+    void update()
+    {
+        if (isRunning()) {
+            log.info("Accepting new connections."); 
 
-				auto ClientSocket = util::make_unique<asio::ip::tcp::socket>(io_context);
-				this->acceptor.accept(*ClientSocket.get());
+            auto ClientSocket = util::make_unique<asio::ip::tcp::socket>(io_context);
+            this->acceptor.accept(*ClientSocket.get());
 
-				//auto error = WSAGetLastError();
+            //auto error = WSAGetLastError();
 
-				if (!ClientSocket->is_open()) {
-					log.warn("Incoming connection failed");
-					return;
-				}
+            if (!ClientSocket->is_open()) {
+                log.warn("Incoming connection failed");
+                return;
+            }
 
-				log.info("Incoming new connection");
-				sockets.emplace_back(std::move(ClientSocket));
+            log.info("Incoming new connection");
+            sockets.emplace_back(std::move(ClientSocket));
 
-				std::thread handlerThread{ &TCPServer<Backend>::processConnection, this, std::ref(*sockets.back()) };
-				threads.emplace_back(std::move(handlerThread));
-			}
-		}
+            std::thread handlerThread { &TCPServer<Backend>::processConnection, this, std::ref(*sockets.back()) };
+            threads.emplace_back(std::move(handlerThread));
+        }
+    }
 
-		bool isRunning()
-		{
-			return running.load();
-		}
+    bool isRunning()
+    {
+        return running.load();
+    }
 
-	private:
-		/**
-	* Handles a BaSyxNativeProvider
-	*/
-		void processConnection(asio::ip::tcp::socket & socket)
-		{
-			log.trace("Processing new connection");
+private:
+    /**
+* Handles a BaSyxNativeProvider
+*/
+    void processConnection(asio::ip::tcp::socket& socket)
+    {
+        log.trace("Processing new connection");
 
-			vab::provider::native::frame::BaSyxNativeFrameProcessor processor{ this->backend };
-			vab::provider::native::NativeProvider provider{ socket, &processor };
+        vab::provider::native::frame::BaSyxNativeFrameProcessor processor { this->backend };
+        vab::provider::native::NativeProvider provider { socket, &processor };
 
-			while (!provider.isClosed()) {
-				provider.update();
-			}
-		}
-	};
+        while (!provider.isClosed()) {
+            provider.update();
+        }
+    }
+};
 };
 };
 
-#endif /* VAB_VAB_PROVIDER_NATIVE_BASYXTCPSERVER_2_H */
\ No newline at end of file
+#endif /* BASYX_SERVER_TCPSERVER_H */
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/anyTypeChecker.h b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/anyTypeChecker.h
index f663d82..f940a6f 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/anyTypeChecker.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/anyTypeChecker.h
@@ -4,52 +4,49 @@
  *      Author: wendel
  */
 
-#ifndef UTIL_ANYTYPECHECKER_H_
-#define UTIL_ANYTYPECHECKER_H_
+#ifndef BASYX_SHARED_ANYTYPECHECKER_H
+#define BASYX_SHARED_ANYTYPECHECKER_H
 
-#include <BaSyx/shared/types.h>
 #include <BaSyx/shared/object.h>
+#include <BaSyx/shared/types.h>
 
 #include <string>
 
 namespace basyx {
 
-namespace PropertyTypeInfo
+namespace PropertyTypeInfo {
+    static constexpr char STRING[] = "string";
+    static constexpr char INT[] = "int";
+    static constexpr char COLLECTION[] = "collection";
+    static constexpr char MAP[] = "map";
+    static constexpr char BOOL[] = "boolean";
+    static constexpr char DOUBLE[] = "double";
+    static constexpr char FLOAT[] = "long";
+    static constexpr char PROPNULL[] = "null";
+    static constexpr char NONETYPE[] = "Type not specified";
+}
+
+static std::string getPropertyTypeInfo(const basyx::object& object)
 {
-	static constexpr char STRING[] = "string";
-	static constexpr char INT[] = "int";
-	static constexpr char COLLECTION[] = "collection";
-	static constexpr char MAP[] = "map";
-	static constexpr char BOOL[] = "boolean";
-	static constexpr char DOUBLE[] = "double";
-	static constexpr char FLOAT[] = "long";
-	static constexpr char PROPNULL[] = "null";
-	static constexpr char NONETYPE[] = "Type not specified";
-}
-
-
-static std::string getPropertyTypeInfo(const basyx::object & object)
-{
-  if ( object.InstanceOf<std::string>() )
-    return PropertyTypeInfo::STRING;
-  if ( object.InstanceOf<int>() )
-    return PropertyTypeInfo::INT;
-  if ( object.InstanceOf<basyx::object::object_list_t>() )
-    return PropertyTypeInfo::COLLECTION;
-  if ( object.InstanceOf<basyx::object::object_map_t>() )
-    return PropertyTypeInfo::MAP;
-  if ( object.InstanceOf<bool>() )
-    return PropertyTypeInfo::BOOL;
-  if ( object.InstanceOf<double>() )
-    return PropertyTypeInfo::DOUBLE;
-  if ( object.InstanceOf<float>() )
-    return PropertyTypeInfo::FLOAT;
-  if ( object.InstanceOf<std::nullptr_t>() )
-    return PropertyTypeInfo::PROPNULL;
-  return PropertyTypeInfo::NONETYPE;
+    if (object.InstanceOf<std::string>())
+        return PropertyTypeInfo::STRING;
+    if (object.InstanceOf<int>())
+        return PropertyTypeInfo::INT;
+    if (object.InstanceOf<basyx::object::object_list_t>())
+        return PropertyTypeInfo::COLLECTION;
+    if (object.InstanceOf<basyx::object::object_map_t>())
+        return PropertyTypeInfo::MAP;
+    if (object.InstanceOf<bool>())
+        return PropertyTypeInfo::BOOL;
+    if (object.InstanceOf<double>())
+        return PropertyTypeInfo::DOUBLE;
+    if (object.InstanceOf<float>())
+        return PropertyTypeInfo::FLOAT;
+    if (object.InstanceOf<std::nullptr_t>())
+        return PropertyTypeInfo::PROPNULL;
+    return PropertyTypeInfo::NONETYPE;
 }
 
 }
 
-
-#endif // !UTIL_ANYTYPECHECKER_H_
+#endif /* BASYX_SHARED_ANYTYPECHECKER_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/enums.h b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/enums.h
index 6f92379..1289a75 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/enums.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/enums.h
@@ -1,24 +1,19 @@
-#ifndef BASYX_ENUMS_H
-#define BASYX_ENUMS_H
+#ifndef BASYX_SHARED_ENUMS_H
+#define BASYX_SHARED_ENUMS_H
 
-namespace basyx
-{
+namespace basyx {
 
-enum class EntityType : char
-{
-	CoManagedEntity = 0,
-	SelfManagedEntity = 1,
+enum class EntityType : char {
+    CoManagedEntity = 0,
+    SelfManagedEntity = 1,
 };
 
-enum class Category : char
-{
-	Constant = 0,
-	Parameter = 1,
-	Variable = 2,
+enum class Category : char {
+    Constant = 0,
+    Parameter = 1,
+    Variable = 2,
 };
 
 };
 
-
-
-#endif
\ No newline at end of file
+#endif /* BASYX_SHARED_ENUMS_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object.h b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object.h
index 5a715ff..36f7fbf 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object.h
@@ -1,3 +1,6 @@
+#ifndef BASYX_SHARED_OBJECT_H
+#define BASYX_SHARED_OBJECT_H
+
 #include <BaSyx/shared/object/object_header.h>
 #include <BaSyx/shared/object/impl/object_cast_impl.h>
 #include <BaSyx/shared/object/impl/object_meta_impl.h>
@@ -5,3 +8,5 @@
 #include <BaSyx/shared/object/impl/object_access_impl.h>
 #include <BaSyx/shared/object/obj_holder.h>
 #include <BaSyx/shared/object/obj_ref_holder.h>
+
+#endif /* BASYX_SHARED_OBJECT_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/bad_object_cast.h b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/bad_object_cast.h
index 4a6af5a..15d1981 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/bad_object_cast.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/bad_object_cast.h
@@ -5,35 +5,35 @@
  *      Author: psota
  */
 
-#ifndef BASYX_object_BAD_object_CAST_H
-#define BASYX_object_BAD_object_CAST_H
+#ifndef BASYX_SHARED_OBJECT_BAD_OBJECT_CAST_H
+#define BASYX_SHARED_OBJECT_BAD_OBJECT_CAST_H
 
 #include <exception>
 #include <memory>
 #include <string>
 
 namespace basyx {
-    // Exception: bad_object_cast
-    // Thrown whenever a bad cast on a basyx::object object is tried
-    class bad_object_cast : public std::bad_cast {
-    private:
-        std::string msg;
+// Exception: bad_object_cast
+// Thrown whenever a bad cast on a basyx::object object is tried
+class bad_object_cast : public std::bad_cast {
+private:
+    std::string msg;
 
-    public:
-        bad_object_cast(const std::type_info& base_type, const std::type_info& casted_type)
-            : msg { "basyx::bad_object_cast: " }
-        {
-            msg.append("Base type: <").append(base_type.name()).append(">");
-            msg.append(", casted type: <").append(casted_type.name()).append(">");
-        };
-
-    public:
-        virtual const char* what() const noexcept override
-        {
-            return msg.c_str();
-        }
+public:
+    bad_object_cast(const std::type_info& base_type, const std::type_info& casted_type)
+        : msg { "basyx::bad_object_cast: " }
+    {
+        msg.append("Base type: <").append(base_type.name()).append(">");
+        msg.append(", casted type: <").append(casted_type.name()).append(">");
     };
 
+public:
+    virtual const char* what() const noexcept override
+    {
+        return msg.c_str();
+    }
+};
+
 };
 
-#endif /* BASYX_object_BAD_object_CAST_H */
+#endif /* BASYX_SHARED_OBJECT_BAD_OBJECT_CAST_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/impl/object_access_impl.h b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/impl/object_access_impl.h
index c21fb3d..e750d69 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/impl/object_access_impl.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/impl/object_access_impl.h
@@ -1,107 +1,110 @@
-#ifndef SHARED_BASYX_OBJECT_IMPL_OBJECT_ACCESS_IMPL_H
-#define SHARED_BASYX_OBJECT_IMPL_OBJECT_ACCESS_IMPL_H
+#ifndef BASYX_SHARED_OBJECT_IMPL_OBJECT_ACCESS_IMPL_H
+#define BASYX_SHARED_OBJECT_IMPL_OBJECT_ACCESS_IMPL_H
 
 template<typename T>
 bool basyx::object::insert(const T & t)
 {
-	if (!this->content)
-		return false;
+    if (!this->content)
+        return false;
 
-	// Check if contained object is list or set
-	switch (content->object_type())
-	{
-	case basyx::type::objectType::List:
-		if (this->InstanceOf<object::list_t<T>>())
-		{
-			auto & vec = this->Get<object::list_t<T>&>();
-			vec.push_back(t);
-			return true;
-		}
-		else if (this->InstanceOf<object::object_list_t>())
-		{
-			auto & vec = this->Get<object::object_list_t&>();
-			vec.emplace_back(t);
-			return true;
-		}
-		break;
-	};
-	return false;
+    // Check if contained object is list or set
+    switch (content->object_type())
+    {
+    case basyx::type::objectType::List:
+        if (this->InstanceOf<object::list_t<T>>())
+        {
+            auto & vec = this->Get<object::list_t<T>&>();
+            vec.push_back(t);
+            return true;
+        }
+        else if (this->InstanceOf<object::object_list_t>())
+        {
+            auto & vec = this->Get<object::object_list_t&>();
+            vec.emplace_back(t);
+            return true;
+        }
+        break;
+    default:
+        break;
+    };
+    return false;
 };
 
 template<typename T>
 bool basyx::object::insertKey(const std::string & key, const T & t, bool override)
 {
-	if (!this->content)
-		return false;
+    if (!this->content)
+        return false;
 
-	// Check if contained object is hashmap
-	if (content->object_type() == basyx::type::objectType::Map)
-	{
-		// Check contained type
-		if (this->InstanceOf<object::object_map_t>())
-		{
-			auto & map = this->Get<object::object_map_t&>();
+    // Check if contained object is hashmap
+    if (content->object_type() == basyx::type::objectType::Map)
+    {
+        // Check contained type
+        if (this->InstanceOf<object::object_map_t>())
+        {
+            auto & map = this->Get<object::object_map_t&>();
 
-			// Check if key already exists
-			if (map.find(key) != map.end())
-			{
-				// if override, set new value, else return false
-				if (override) {
-					map[key] = t;
-					return true;
-				};
+            // Check if key already exists
+            if (map.find(key) != map.end())
+            {
+                // if override, set new value, else return false
+                if (override) {
+                    map[key] = t;
+                    return true;
+                };
 
-				return false;
-			}
-			else // key doesn't exist, just insert object
-			{
-				map.emplace(key, t);
-				return true;
-			}
-		}
-	};
+                return false;
+            }
+            else // key doesn't exist, just insert object
+            {
+                map.emplace(key, t);
+                return true;
+            }
+        }
+    };
 
-	return false;
+    return false;
 };
 
 template<typename T>
 bool basyx::object::remove(const T & t)
 {
-	if (!this->content)
-		return false;
+    if (!this->content)
+        return false;
 
-	// Check if contained object is list or set
-	switch (content->object_type())
-	{
-	case basyx::type::objectType::List:
-		auto & list = this->Get<object::list_t<T>&>();
-		list.erase(std::remove(list.begin(), list.end(), t), list.end());
-		return true;
-		break;
-	};
-	return false;
+    // Check if contained object is list or set
+    switch (content->object_type())
+    {
+    case basyx::type::objectType::List:
+    {
+        auto & list = this->Get<object::list_t<T>&>();
+        list.erase(std::remove(list.begin(), list.end(), t), list.end());
+        return true;
+    };
+    default:
+        break;
+    };
+    return false;
 }
 
 inline bool basyx::object::remove(basyx::object & obj)
 {
-	auto valueType = obj.GetValueType();
-	switch(valueType)
-	{
-	case basyx::type::valueType::Bool:
-		return this->remove(obj.Get<const bool>());
-		break;
-	case basyx::type::valueType::Int:
-		return this->remove(obj.Get<const int>());
-		break;
-	case basyx::type::valueType::String:
-		return this->remove(obj.Get<const std::string>());
-		break;
-	case basyx::type::valueType::Float:
-		return this->remove(obj.Get<const double>());
-		break;
-	};
+    auto valueType = obj.GetValueType();
+    switch(valueType)
+    {
+    case basyx::type::valueType::Bool:
+        return this->remove(obj.Get<const bool>());
+    case basyx::type::valueType::Int:
+        return this->remove(obj.Get<const int>());
+    case basyx::type::valueType::String:
+        return this->remove(obj.Get<const std::string>());
+    case basyx::type::valueType::Float:
+        return this->remove(obj.Get<const double>());
+    default:
+        break;
+    };
 
-	return false;
+    return false;
 };
 
-#endif /* SHARED_BASYX_OBJECT_IMPL_OBJECT_ACCESS_IMPL_H */
+#endif /* BASYX_SHARED_OBJECT_IMPL_OBJECT_ACCESS_IMPL_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/impl/object_cast_impl.h b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/impl/object_cast_impl.h
index d169a34..76b9453 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/impl/object_cast_impl.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/impl/object_cast_impl.h
@@ -1,5 +1,5 @@
-#ifndef SHARED_BASYX_OBJECT_IMPL_OBJECT_CAST_IMPL_H
-#define SHARED_BASYX_OBJECT_IMPL_OBJECT_CAST_IMPL_H
+#ifndef BASYX_SHARED_OBJECT_IMPL_OBJECT_CAST_IMPL_H
+#define BASYX_SHARED_OBJECT_IMPL_OBJECT_CAST_IMPL_H
 
 #include <BaSyx/shared/object/object_header.h>
 #include <BaSyx/shared/object/obj_holder.h>
@@ -66,4 +66,4 @@
 	return object_cast<T>(const_cast<object*>(operand));
 }
 
-#endif /* SHARED_BASYX_OBJECT_IMPL_OBJECT_CAST_IMPL_H */
+#endif /* BASYX_SHARED_OBJECT_IMPL_OBJECT_CAST_IMPL_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/impl/object_factories_impl.h b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/impl/object_factories_impl.h
index 4279fef..3c38594 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/impl/object_factories_impl.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/impl/object_factories_impl.h
@@ -1,5 +1,5 @@
-#ifndef SHARED_BASYX_OBJECT_IMPL_OBJECT_FACTORIES_IMPL_H
-#define SHARED_BASYX_OBJECT_IMPL_OBJECT_FACTORIES_IMPL_H
+#ifndef BASYX_SHARED_OBJECT_IMPL_OBJECT_FACTORIES_IMPL_H
+#define BASYX_SHARED_OBJECT_IMPL_OBJECT_FACTORIES_IMPL_H
 
 #include <BaSyx/util/printer.h>
 #include <BaSyx/util/util.h>
@@ -53,4 +53,4 @@
 	return basyx::detail::functionWrapper::wrap_func(util::make_function(std::forward<Args>(args)...));
 };
 
-#endif /* SHARED_BASYX_OBJECT_IMPL_OBJECT_FACTORIES_IMPL_H */
+#endif /* BASYX_SHARED_OBJECT_IMPL_OBJECT_FACTORIES_IMPL_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/impl/object_meta_impl.h b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/impl/object_meta_impl.h
index 50b7cec..6abe59e 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/impl/object_meta_impl.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/impl/object_meta_impl.h
@@ -1,5 +1,5 @@
-#ifndef SHARED_BASYX_OBJECT_IMPL_OBJECT_META_IMPL_H
-#define SHARED_BASYX_OBJECT_IMPL_OBJECT_META_IMPL_H
+#ifndef BASYX_SHARED_OBJECT_IMPL_OBJECT_META_IMPL_H
+#define BASYX_SHARED_OBJECT_IMPL_OBJECT_META_IMPL_H
 
 template <typename T>
 bool basyx::object::operator!=(const T& rhs) const
@@ -17,4 +17,4 @@
 }
 
 
-#endif /* SHARED_BASYX_OBJECT_IMPL_OBJECT_META_IMPL_H */
+#endif /* BASYX_SHARED_OBJECT_IMPL_OBJECT_META_IMPL_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/obj_error.h b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/obj_error.h
index 34114c7..304bc1c 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/obj_error.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/obj_error.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_ENUM_ERROR_H
-#define BASYX_ENUM_ERROR_H
+#ifndef BASYX_SHARED_OBJECT_OBJ_ERROR_H
+#define BASYX_SHARED_OBJECT_OBJ_ERROR_H
 
 #include <string>
 
@@ -26,4 +26,4 @@
 }
 }
 
-#endif
+#endif /* BASYX_SHARED_OBJECT_OBJ_ERROR_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/obj_error_holder.h b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/obj_error_holder.h
index 9619fb7..c4e58dd 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/obj_error_holder.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/obj_error_holder.h
@@ -5,8 +5,8 @@
  *      Author: psota
  */
 
-#ifndef BASYX_object_error_HOLDER_H
-#define BASYX_object_error_HOLDER_H
+#ifndef BASYX_SHARED_OBJECT_OBJ_ERROR_HOLDER_H
+#define BASYX_SHARED_OBJECT_OBJ_ERROR_HOLDER_H
 
 #include <memory>
 #include <string>
@@ -76,4 +76,4 @@
 }
 }
 
-#endif /* BASYX_object_error_HOLDER_H */
+#endif /* BASYX_SHARED_OBJECT_OBJ_ERROR_HOLDER_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/obj_function.h b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/obj_function.h
index 9902e82..d86035c 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/obj_function.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/obj_function.h
@@ -1,5 +1,5 @@
-#ifndef OBJ_FUNCTION_H
-#define OBJ_FUNCTION_H
+#ifndef BASYX_SHARED_OBJECT_OBJ_FUNCTION_H
+#define BASYX_SHARED_OBJECT_OBJ_FUNCTION_H
 
 #include <functional>
 
@@ -34,6 +34,18 @@
 		return func(&obj);
 	};
 
+	// Wrap void function with no arguments
+	static functionWrapper wrap_func(std::function<void(void)> f)
+	{
+		functionWrapper fw;
+		fw.func = [f](basyx::object*)
+		{
+			f();
+			return basyx::object::make_null();
+		};
+		return fw;
+	};
+
 	// Wrap function with no arguments
 	template<typename RetType>
 	static functionWrapper wrap_func(std::function<RetType(void)> f)
@@ -109,4 +121,4 @@
 }
 
 
-#endif /* OBJ_FUNCTION_H */
+#endif /* BASYX_SHARED_OBJECT_OBJ_FUNCTION_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/obj_holder.h b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/obj_holder.h
index d39d6a6..17b137f 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/obj_holder.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/obj_holder.h
@@ -5,8 +5,8 @@
  *      Author: psota
  */
 
-#ifndef BASYX_object_HOLDER_H
-#define BASYX_object_HOLDER_H
+#ifndef BASYX_SHARED_OBJECT_OBJ_HOLDER_H
+#define BASYX_SHARED_OBJECT_OBJ_HOLDER_H
 
 #include <memory>
 #include <string>
@@ -83,4 +83,4 @@
 }
 }
 
-#endif /* BASYX_object_HOLDER_H */
+#endif /* BASYX_SHARED_OBJECT_OBJ_HOLDER_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/obj_placeholder.h b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/obj_placeholder.h
index d1bff64..c157c66 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/obj_placeholder.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/obj_placeholder.h
@@ -5,8 +5,8 @@
  *      Author: psota
  */
 
-#ifndef BASYX_object_PLACEHOLDER_H
-#define BASYX_object_PLACEHOLDER_H
+#ifndef BASYX_SHARED_OBJECT_OBJ_PLACEHOLDER_H
+#define BASYX_SHARED_OBJECT_OBJ_PLACEHOLDER_H
 
 #include <BaSyx/shared/object/object_type.h>
 
@@ -43,4 +43,4 @@
 }
 };
 
-#endif /* BASYX_object_PLACEHOLDER_H */
+#endif /* BASYX_SHARED_OBJECT_OBJ_PLACEHOLDER_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/obj_ref_holder.h b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/obj_ref_holder.h
index 7619afb..59dbbdb 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/obj_ref_holder.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/obj_ref_holder.h
@@ -5,8 +5,8 @@
  *      Author: psota
  */
 
-#ifndef BASYX_object_ref_HOLDER_H
-#define BASYX_object_ref_HOLDER_H
+#ifndef BASYX_SHARED_OBJECT_OBJ_REF_HOLDER_H
+#define BASYX_SHARED_OBJECT_OBJ_REF_HOLDER_H
 
 #include <memory>
 #include <string>
@@ -81,4 +81,4 @@
 }
 }
 
-#endif /* BASYX_object_HOLDER_H */
+#endif /* BASYX_SHARED_OBJECT_OBJ_REF_HOLDER_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/object_header.h b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/object_header.h
index 806c110..6264f9b 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/object_header.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/object_header.h
@@ -5,8 +5,8 @@
  *      Author: psota
  */
 
-#ifndef BASYX_object_object_header_H
-#define BASYX_object_object_header_H
+#ifndef BASYX_SHARED_OBJECT_OBJECT_HEADER_H
+#define BASYX_SHARED_OBJECT_OBJECT_HEADER_H
 
 #include <cstddef>
 #include <memory>
@@ -223,4 +223,4 @@
 	};
 };
 
-#endif /* BASYX_object_object_H */
+#endif /* BASYX_SHARED_OBJECT_OBJECT_HEADER_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/object_type.h b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/object_type.h
index 8a3f762..a935b0d 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/object_type.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/object/object_type.h
@@ -1,12 +1,28 @@
-#ifndef BASYX_object_object_TYPE_H
-#define BASYX_object_object_TYPE_H
+#ifndef BASYX_SHARED_OBJECT_OBJECT_TYPE_H
+#define BASYX_SHARED_OBJECT_OBJECT_TYPE_H
 
 #include <string>
 #include <vector>
 #include <unordered_set>
 #include <unordered_map>
 
+template<typename T>
+struct dataTypeMapper
+{
 
+};
+
+template<>
+struct dataTypeMapper<float>
+{
+	static constexpr char datatype_string[] = "xsd:float";
+};
+
+template<>
+struct dataTypeMapper<int>
+{
+	static constexpr char datatype_string[] = "xsd:integer";
+};
 
 namespace basyx {
 
@@ -162,4 +178,4 @@
 	template<> inline std::string to_string<basyx::type::valueType::Object>() { return "Object"; };
 }
 
-#endif
\ No newline at end of file
+#endif /* BASYX_SHARED_OBJECT_OBJECT_TYPE_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/serialization/json.h b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/serialization/json.h
index f9eacd3..f3de345 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/serialization/json.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/serialization/json.h
@@ -1,6 +1,6 @@
-#ifndef _JSON_H
-#define _JSON_H
+#ifndef BASYX_SHARED_SERIALIZATION_JSON_H
+#define BASYX_SHARED_SERIALIZATION_JSON_H
 
 #include <BaSyx/shared/serialization/json/json.h>
 
-#endif /* _JSON_H */
+#endif /* BASYX_SHARED_SERIALIZATION_JSON_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/serialization/json/json.h b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/serialization/json/json.h
index 336a14a..6afab09 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/serialization/json/json.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/serialization/json/json.h
@@ -5,8 +5,8 @@
  *      Author: psota
  */
 
-#ifndef BASYX_SERIALIZATION_JSON_JSON_H
-#define BASYX_SERIALIZATION_JSON_JSON_H
+#ifndef BASYX_SHARED_SERIALIZATION_JSON_JSON_H
+#define BASYX_SHARED_SERIALIZATION_JSON_JSON_H
 
 #include <nlohmann/json.hpp>
 
@@ -49,4 +49,4 @@
 };
 };
 
-#endif /* BASYX_SERIALIZATION_JSON_JSON_H */
+#endif /* BASYX_SHARED_SERIALIZATION_JSON_JSON_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/serialization/json/json_deserializer.h b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/serialization/json/json_deserializer.h
index 52688eb..8a46858 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/serialization/json/json_deserializer.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/serialization/json/json_deserializer.h
@@ -5,8 +5,8 @@
  *      Author: psota
  */
 
-#ifndef BASYX_JSON_DESERIALIZER_H
-#define BASYX_JSON_DESERIALIZER_H
+#ifndef BASYX_SHARED_SERIALIZATION_JSON_JSON_DESERIALIZER_H
+#define BASYX_SHARED_SERIALIZATION_JSON_JSON_DESERIALIZER_H
 
 #include <nlohmann/json.hpp>
 
@@ -111,6 +111,8 @@
 					return deserialize_helper::list_t<double>(json_array);
 				case basyx::type::valueType::Object:
 					return deserialize_helper::object_list(json_array);
+                                default:
+                                    break;
 				};
 			}
 
@@ -159,4 +161,4 @@
 };
 };
 
-#endif
+#endif /* BASYX_SHARED_SERIALIZATION_JSON_JSON_DESERIALIZER_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/serialization/json/json_serializer.h b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/serialization/json/json_serializer.h
index 8917501..610ce09 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/serialization/json/json_serializer.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/serialization/json/json_serializer.h
@@ -5,8 +5,8 @@
  *      Author: psota
  */
 
-#ifndef BASYX_SERIALIZATION_JSON_JSON_SERIALIZER_H
-#define BASYX_SERIALIZATION_JSON_JSON_SERIALIZER_H
+#ifndef BASYX_SHARED_SERIALIZATION_JSON_JSON_SERIALIZER_H
+#define BASYX_SHARED_SERIALIZATION_JSON_JSON_SERIALIZER_H
 
 #include <nlohmann/json.hpp>
 
@@ -63,4 +63,4 @@
 };
 };
 
-#endif /* BASYX_SERIALIZATION_JSON_JSON_SERIALIZER_H */
+#endif /* BASYX_SHARED_SERIALIZATION_JSON_JSON_SERIALIZER_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/serialization/json/typeid.h b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/serialization/json/typeid.h
index d2276f4..1b83a4f 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/serialization/json/typeid.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/serialization/json/typeid.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_JSON_TYPEID_H
-#define BASYX_JSON_TYPEID_H
+#ifndef BASYX_SHARED_SERIALIZATION_JSON_TYPEID_H
+#define BASYX_SHARED_SERIALIZATION_JSON_TYPEID_H
 
 #include <string>
 
@@ -54,4 +54,4 @@
 template <typename T>
 constexpr char basyx::serialization::basysType<T>::string[];
 
-#endif /* BASYX_JSON_TYPEID_H */
+#endif /* BASYX_SHARED_SERIALIZATION_JSON_TYPEID_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/types.h b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/types.h
index d9a106c..8adda9b 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/shared/types.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/shared/types.h
@@ -4,8 +4,8 @@
  * Define type IDs
  * ************************************************************************************************/
 
-#ifndef BASYX_TYPES_H
-#define BASYX_TYPES_H
+#ifndef BASYX_SHARED_TYPES_H
+#define BASYX_SHARED_TYPES_H
 
 #include <set>
 #include <unordered_map>
@@ -51,4 +51,4 @@
 #define BASYX_FRAMESIZE_SIZE 4
 #define BASYX_STRINGSIZE_SIZE 4
 
-#endif /* BASYX_TYPES_H */
+#endif /* BASYX_SHARED_TYPES_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/IElement.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/IElement.h
deleted file mode 100644
index 09c4b67..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/IElement.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * IElement.h
- *
- *  Created on: 29.04.2018
- *      Author: kuhn, wendel
- */
-
-#ifndef API_IELEMENT_H_
-#define API_IELEMENT_H_
-
-#include <string>
-
-/* *********************************************************************************
- * IElement class - Base class for reflexive BaSys elements
- * *********************************************************************************/
-class IElement {
-public:
-	virtual ~IElement() = default;
-
-	virtual void setId(const std::string & id) = 0;
-	virtual std::string getId() const = 0;
-};
-
-
-#endif /* API_IELEMENT_H_ */
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/ISubModel.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/ISubModel.h
deleted file mode 100644
index 0a51f2d..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/ISubModel.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * ISubModel.h
- *
- *      Author: kuhn, wendel
- */
-
-#ifndef API_ISUBMODEL_H_
-#define API_ISUBMODEL_H_
-
-
- /* *********************************************************************************
-  * Includes
-  * *********************************************************************************/
-
-  // StdC++ includes
-#include <map>
-#include <string>
-
-// BaSyx includes
-#include <BaSyx/submodel/api/submodelelement/property/IProperty.h>
-#include <BaSyx/submodel/api/qualifier/IHasSemantics.h>
-#include <BaSyx/submodel/api/qualifier/IIdentifiable.h>
-#include <BaSyx/submodel/api/qualifier/IHasDataSpecification.h>
-#include <BaSyx/submodel/api/qualifier/IHasKind.h>
-#include <BaSyx/submodel/api/submodelelement/operation/IOperation.h>
-#include <BaSyx/submodel/map/IVABElementContainer.h>
-#include <BaSyx/shared/types.h>
-
-
-namespace basyx {
-namespace submodel {
-
-
-/* *********************************************************************************
- * Sub model interface class
- * *********************************************************************************/
-class ISubModel : 
-	public virtual IHasSemantics, 
-	public virtual IIdentifiable,
-    public virtual IQualifiable,
-	public virtual IHasDataSpecification,
-	public virtual IHasKind,
-	public map::IVABElementContainer
-{
-public:
-	struct Path {
-		static constexpr char Submodelelement[] = "submodelElement";
-		static constexpr char DataElements[] = "dataElements";
-		static constexpr char Operations[] = "operations";
-		static constexpr char ModelType[] = "Submodel";
-	};
-public:
-	virtual ~ISubModel() = default;
-
-	virtual basyx::specificMap_t<ISubmodelElement> getSubmodelElements() const = 0;
-	virtual basyx::specificMap_t<IDataElement> getDataElements() const = 0;
-	virtual basyx::specificMap_t<IOperation> getOperations() const = 0;
-};
-
-}
-}
-
-
-#endif /* API_ISUBMODEL_H_ */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/dataspecification/IDataSpecification.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/dataspecification/IDataSpecification.h
deleted file mode 100644
index e4eafd1..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/dataspecification/IDataSpecification.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * IDataSpecification.h
- *
- *      Author: wendel
- */
-
-#ifndef BASYX_METAMODEL_IDATASPECIFICATION_H_
-#define BASYX_METAMODEL_IDATASPECIFICATION_H_
-
-#include <BaSyx/submodel/api/dataspecification/IDataSpecificationContent.h>
-
-#include <BaSyx/submodel/api/qualifier/IIdentifiable.h>
-#include <BaSyx/submodel/api/qualifier/IReferable.h>
-
-#include <string>
-
-namespace basyx {
-namespace submodel {
-
-class IDataSpecification
-  : public virtual submodel::IIdentifiable
-  , public virtual submodel::IReferable
-{
-public:
-  struct Path
-  {
-    static constexpr char Content[] = "content";
-  };
-public:
-  virtual ~IDataSpecification() = default;
-
-  virtual std::shared_ptr<IDataSpecificationContent> getContent() const = 0;
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/dataspecification/IDataSpecificationContent.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/dataspecification/IDataSpecificationContent.h
deleted file mode 100644
index 4b95359..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/dataspecification/IDataSpecificationContent.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * IDataSpecification.h
- *
- *      Author: wendel
- */
-
-#ifndef BASYX_METAMODEL_IDATASPECIFICATION_CONTENT_H_
-#define BASYX_METAMODEL_IDATASPECIFICATION_CONTENT_H_
-
-#include <BaSyx/submodel/api/qualifier/IIdentifiable.h>
-#include <BaSyx/submodel/api/qualifier/IReferable.h>
-
-namespace basyx {
-namespace submodel {
-
-class IDataSpecificationContent
-{
-public:
-  virtual ~IDataSpecificationContent() = default;
-};
-
-}
-}
-
-#endif
-
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/dataspecification/IDataSpecificationIEC61360.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/dataspecification/IDataSpecificationIEC61360.h
deleted file mode 100644
index 370b2c0..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/dataspecification/IDataSpecificationIEC61360.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * IDataSpecification.h
- *
- *      Author: wendel
- */
-
-#ifndef BASYX_METAMODEL_IDATASPECIFICATION_I_DATASPECIFICATIONIEC61630_H_
-#define BASYX_METAMODEL_IDATASPECIFICATION_I_DATASPECIFICATIONIEC61630_H_
-
-#include <BaSyx/submodel/api/dataspecification/IDataSpecificationContent.h>
-#include <BaSyx/submodel/api/dataspecification/datatypes/DataTypeIEC61360.h>
-#include <BaSyx/submodel/api/dataspecification/datatypes/LevelType.h>
-
-#include <BaSyx/submodel/api/reference/IReference.h>
-
-#include <BaSyx/submodel/api/submodelelement/langstring/ILangStringSet.h>
-
-#include <BaSyx/shared/object.h>
-
-#include <string>
-
-namespace basyx {
-namespace submodel {
-
-class IDataSpecificationIEC61360
-  : public virtual IDataSpecificationContent
-{
-public:
-struct Path
-{
-	static constexpr char PreferredName[] = "preferredName";
-	static constexpr char ShortName[] = "shortName";
-	static constexpr char Unit[] = "unit";
-	static constexpr char UnitId[] = "unitId";
-	static constexpr char SourceOfDefinition[] = "sourceOfDefinition";
-	static constexpr char Symbol[] = "symbol";
-	static constexpr char DataType[] = "dataType";
-	static constexpr char Definition[] = "definition";
-	static constexpr char ValueFormat[] = "valueFormat";
-	static constexpr char ValueList[] = "valueList";
-	static constexpr char ValueId[] = "valueId";
-	static constexpr char LevelType[] = "levelType";
-};
-
-public:
-  virtual ~IDataSpecificationIEC61360() = default;
-
-  virtual std::shared_ptr<ILangStringSet> PreferredName() = 0;
-  virtual std::shared_ptr<ILangStringSet> ShortName() = 0;
-  virtual std::shared_ptr<ILangStringSet> Definition() = 0;
-
-  virtual std::string getUnit() const = 0;
-  virtual std::shared_ptr<IReference> getUnitId() const = 0;
-  virtual std::string getSourceOfDefinition() const = 0;
-  virtual DataTypeIEC61360 getDataType() const = 0;
-  virtual std::string getValueFormat() const = 0;
-  virtual basyx::object getValueList() const = 0;
-  virtual std::shared_ptr<submodel::IReference> getValueId() const = 0;
-  virtual LevelType getLevelType() const = 0;
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/dataspecification/datatypes/DataTypeIEC61360.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/dataspecification/datatypes/DataTypeIEC61360.h
deleted file mode 100644
index b9b3b0b..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/dataspecification/datatypes/DataTypeIEC61360.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * DataTypeIEC61360.h
- *
- *      Author: wendel
- */
-
-#ifndef BASYX_AAS_DATASPECIFICATION_DATATYPEIEC61360_H_
-#define BASYX_AAS_DATASPECIFICATION_DATATYPEIEC61360_H_
-
-#include <string>
-#include <unordered_map>
-
-#include <BaSyx/util/util.h>
-
-namespace basyx {
-namespace submodel {
-
-	enum class DataTypeIEC61360 : char
-	{
-		Date,
-		String,
-		String_Translatable,
-		Real_Measure,
-		Real_Count,
-		Real_Currency,
-		Boolean,
-		Url,
-		Rational,
-		Rational_Measure,
-		Time,
-		Timestamp
-	};
-}
-}
-
-namespace util {
-	const std::string & to_string(basyx::submodel::DataTypeIEC61360 type);
-
-	template<>
-	basyx::submodel::DataTypeIEC61360 from_string<basyx::submodel::DataTypeIEC61360>(const std::string & str);
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/dataspecification/datatypes/LevelType.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/dataspecification/datatypes/LevelType.h
deleted file mode 100644
index 5853940..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/dataspecification/datatypes/LevelType.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * LevelType.h
- *
- *      Author: wendel
- */
-
-#ifndef BASYX_AAS_DATASPECIFICATION_LEVELTYPE_H_
-#define BASYX_AAS_DATASPECIFICATION_LEVELTYPE_H_
-
-#include <unordered_map>
-#include <string>
-
-#include <BaSyx/util/util.h>
-
-namespace basyx {
-namespace submodel {
-
-	enum class LevelType : char
-	{
-	  Min,
-	  Max,
-	  Nom,
-	  Typ
-	};
-}
-}
-
-namespace util {
-
-	const std::string & to_string(basyx::submodel::LevelType levelType);
-
-	template<>
-	basyx::submodel::LevelType from_string<basyx::submodel::LevelType>(const std::string & str);
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/identifier/IIdentifier.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/identifier/IIdentifier.h
deleted file mode 100644
index 3f3683a..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/identifier/IIdentifier.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * IIdentifier.h
- *
- *      Author: wendel
- */
-
-#ifndef BASYX_METAMODEL_IIDENTIFIER_H_
-#define BASYX_METAMODEL_IIDENTIFIER_H_
-
-#include <string>
-
-namespace basyx {
-namespace submodel {
-
-class IIdentifier
-{
-public:
-	struct Path {
-		static constexpr char IdentifierPath[] = "identifierPath";
-		static constexpr char IdType[] = "idType";
-		static constexpr char Id[] = "id";
-	};
-public:
-  virtual ~IIdentifier() = default;
-
-  /**
-   * Get value of 'idType' property
-   */
-  virtual std::string getIdType() const = 0;
-
-  /**
-   * Get value of 'id' property
-   */
-  virtual std::string getId() const = 0;
-};
-
-}
-}
-
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/parts/IConceptDescription.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/parts/IConceptDescription.h
deleted file mode 100644
index ff585ba..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/parts/IConceptDescription.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * IConceptDescription.h
- *
- *      Author: wendel
- */ 
-
-#ifndef BASYX_METAMODEL_IConceptDescription_H_
-#define BASYX_METAMODEL_IConceptDescription_H_
-
-#include "BaSyx/submodel/api/qualifier/IHasDataSpecification.h"
-#include "BaSyx/submodel/api/qualifier/IIdentifiable.h"
-
-#include <string>
-#include <vector>
-
-namespace basyx {
-namespace submodel {
-
-class IConceptDescription : 
-	public virtual submodel::IHasDataSpecification,
-	public virtual submodel::IIdentifiable
-{
-public:
-  struct Path
-  {
-    static constexpr char ModelType[] = "ConceptDescription";
-    static constexpr char IsCaseOf[] = "isCaseOf";
-  };
-
-public:
-	virtual ~IConceptDescription() = default;
-
-	virtual basyx::specificCollection_t<submodel::IReference> getIsCaseOf() const = 0;
-	virtual void setIsCaseOf(const basyx::specificCollection_t<submodel::IReference> & ref) = 0;
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/qualifier/IAdministrativeInformation.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/qualifier/IAdministrativeInformation.h
deleted file mode 100644
index d1af173..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/qualifier/IAdministrativeInformation.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * IAdministrativeInformation.h
- *
- *      Author: wendel
- */ 
-
-#ifndef BASYX_METAMODEL_IAdministrativeInformation_H_
-#define BASYX_METAMODEL_IAdministrativeInformation_H_
-
-
-#include <BaSyx/submodel/api/qualifier/IHasDataSpecification.h>
-
-#include <string>
-
-namespace basyx {
-namespace submodel {
-
-
-class IAdministrativeInformation : 
-  public virtual IHasDataSpecification
-{
-public:
-struct Path {
-	static constexpr char AdministrationPath[] = "administrationPath";
-	static constexpr char Version[] = "version";
-	static constexpr char Revision[] = "revision";
-};
-public:
-  virtual ~IAdministrativeInformation() = default;
-
-  virtual std::string getVersion() const = 0;
-  virtual std::string getRevision() const = 0;
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/qualifier/IHasDataSpecification.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/qualifier/IHasDataSpecification.h
deleted file mode 100644
index e6288ae..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/qualifier/IHasDataSpecification.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * IHasDataSpecification.h
- *
- *      Author: wendel
- */
-
-#ifndef BASYX_METAMODEL_IHasDataSpecification_H_
-#define BASYX_METAMODEL_IHasDataSpecification_H_
-
-
-#include <BaSyx/submodel/api/reference/IReference.h>
-#include <BaSyx/submodel/api/identifier/IIdentifier.h>
-#include <BaSyx/shared/types.h>
-
-namespace basyx {
-namespace submodel {
-
-class IHasDataSpecification
-{
-public:
-	struct Path {
-		static constexpr char HasDataSpecification[] = "hasDataSpecification";
-	};
-public:
-  virtual ~IHasDataSpecification() = default;
-
-  virtual basyx::specificCollection_t<IReference> getDataSpecificationReferences() const = 0;
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/qualifier/IHasKind.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/qualifier/IHasKind.h
deleted file mode 100644
index feb4d34..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/qualifier/IHasKind.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * IHasKind.h
- *
- *      Author: wendel
- */ 
-
-#ifndef BASYX_METAMODEL_IHASKIND_H_
-#define BASYX_METAMODEL_IHASKIND_H_
-
-#include <string>
-
-#include <BaSyx/util/util.h>
-
-namespace basyx {
-namespace submodel {
-
-enum class Kind : char
-{
-	NotSpecified = 0,
-	Type = 1,
-	Instance = 2,
-};
-
-class IHasKind
-{
-public:
-	struct Path {
-		static constexpr char Kind[] = "kind";
-	};
-public:
-  virtual ~IHasKind() = default;
-
-  virtual Kind getHasKindReference() const = 0;
-};
-
-
-}
-}
-
-namespace util {
-	const std::string & to_string(basyx::submodel::Kind kind);
-
-	template<>
-	basyx::submodel::Kind from_string<basyx::submodel::Kind>(const std::string & str);
-}
-
-#endif
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/qualifier/IHasSemantics.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/qualifier/IHasSemantics.h
deleted file mode 100644
index 714e8bd..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/qualifier/IHasSemantics.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * IHasSemantics.h
- *
- *      Author: wendel
- */ 
-
-#ifndef BASYX_METAMODEL_IHasSemantics_H_
-#define BASYX_METAMODEL_IHasSemantics_H_
-
-#include <BaSyx/submodel/api/reference/IReference.h>
-
-
-#include <memory>
-
-
-namespace basyx {
-namespace submodel {
-
-class IHasSemantics
-{
-public:
-	struct Path {
-		static constexpr char SemanticId[] = "semanticId";
-	};
-public:
-  virtual ~IHasSemantics() = default;
-
-  virtual std::shared_ptr<IReference> getSemanticId() const = 0;
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/qualifier/IIdentifiable.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/qualifier/IIdentifiable.h
deleted file mode 100644
index efb15a5..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/qualifier/IIdentifiable.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * IIdentifiable.h
- *
- *      Author: wendel
- */ 
-
-#ifndef BASYX_METAMODEL_IIdentifiable_H_
-#define BASYX_METAMODEL_IIdentifiable_H_
-
-#include <BaSyx/submodel/api/identifier/IIdentifier.h>
-#include <BaSyx/submodel/api/qualifier/IAdministrativeInformation.h>
-#include <BaSyx/shared/types.h>
-
-#include <BaSyx/submodel/api/qualifier/IReferable.h>
-
-#include <string>
-#include <memory>
-
-namespace basyx {
-namespace submodel {
-
-class IIdentifiable 
-  : public virtual IReferable
-{
-public:
-  struct Path
-  {
-    static constexpr char Administration[] = "administration";
-    static constexpr char Identification[] = "identification";
-  };
-public:
-  virtual ~IIdentifiable() = default;
-
-  virtual std::shared_ptr<IAdministrativeInformation> getAdministration() const = 0;
-  virtual std::shared_ptr<IIdentifier> getIdentification() const = 0;
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/qualifier/IReferable.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/qualifier/IReferable.h
deleted file mode 100644
index 78c7863..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/qualifier/IReferable.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * IReferable.h
- *
- *      Author: wendel
- */
-
-#ifndef BASYX_METAMODEL_IREFERABLE_H_
-#define BASYX_METAMODEL_IREFERABLE_H_
-
-#include <BaSyx/submodel/api/reference/IReference.h>
-#include <BaSyx/submodel/map/qualifier/Description.h>
-
-#include <string>
-#include <memory>
-
-namespace basyx {
-namespace submodel {
-
-class IReferable
-{
-public:
-	struct Path {
-		static constexpr char IdShort[] = "idShort";
-		static constexpr char Category[] = "category";
-		static constexpr char Description[] = "description";
-		static constexpr char Parent[] = "parent";
-	};
-public:
-	virtual ~IReferable() = default;
-
-	virtual std::string getIdShort() const = 0;
-	virtual std::string getCategory() const = 0;
-	virtual Description getDescription() const = 0;
-	virtual std::shared_ptr<IReference> getParent() const = 0;
-};
-
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/qualifier/qualifiable/IConstraint.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/qualifier/qualifiable/IConstraint.h
deleted file mode 100644
index 0e10bef..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/qualifier/qualifiable/IConstraint.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * IConstraint.h
- *
- *      Author: wendel
- */
-
-#ifndef BASYX_METAMODEL_ICONSTRAINT_H_
-#define BASYX_METAMODEL_ICONSTRAINT_H_
-
-
-namespace basyx {
-namespace submodel {
-
-class IConstraint
-{
-public:
-	struct Path {
-		static constexpr char ModelType[] = "Constraint";
-	};
-public:
-	virtual ~IConstraint() = default;
-};
-
-}
-}
-
-#endif
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/qualifier/qualifiable/IFormula.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/qualifier/qualifiable/IFormula.h
deleted file mode 100644
index e03723b..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/qualifier/qualifiable/IFormula.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * IFormula.h
- *
- *      Author: wendel
- */ 
-
-#ifndef BASYX_METAMODEL_IFormula_H_
-#define BASYX_METAMODEL_IFormula_H_
-
-#include <BaSyx/submodel/api/reference/IReference.h>
-#include <BaSyx/shared/types.h>
-#include <BaSyx/submodel/api/qualifier/qualifiable/IConstraint.h>
-
-#include <vector>
-
-
-namespace basyx {
-namespace submodel {
-
-class IFormula : public IConstraint
-{
-public:
-  struct Path {
-    static constexpr char Dependson[] = "dependsOn";
-    static constexpr char Modeltype[] = "Formula";
-  };
-
-public:
-  virtual ~IFormula() = default;
-
-  virtual basyx::specificCollection_t<IReference> getDependsOn() const = 0;
-};
-
-}
-}
-
-#endif
-
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/qualifier/qualifiable/IQualifiable.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/qualifier/qualifiable/IQualifiable.h
deleted file mode 100644
index 5838630..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/qualifier/qualifiable/IQualifiable.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * IQualifiable.h
- *
- *      Author: wendel
- */ 
-
-#ifndef BASYX_METAMODEL_IQualifiable_H_
-#define BASYX_METAMODEL_IQualifiable_H_
-
-
-#include <BaSyx/submodel/api/qualifier/qualifiable/IConstraint.h>
-#include <BaSyx/shared/types.h>
-
-#include <vector>
-#include <memory>
-
-namespace basyx {
-namespace submodel {
-
-class IQualifiable
-{
-public:
-	struct Path {
-		static constexpr char Constraints[] = "constraints";
-	};
-public:
-	virtual ~IQualifiable() = default;
-
-	virtual basyx::specificCollection_t<IConstraint> getQualifier() const = 0;
-};
-
-}
-}
-
-#endif
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/qualifier/qualifiable/IQualifier.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/qualifier/qualifiable/IQualifier.h
deleted file mode 100644
index 4c9201b..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/qualifier/qualifiable/IQualifier.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * IQualifier.h
- *
- *      Author: wendel
- */ 
-
-#ifndef BASYX_METAMODEL_IQualifier_H_
-#define BASYX_METAMODEL_IQualifier_H_
-
-#include <BaSyx/submodel/api/reference/IReference.h>
-#include <BaSyx/submodel/api/qualifier/IHasSemantics.h>
-#include <BaSyx/shared/types.h>
-#include <BaSyx/shared/object.h>
-#include <BaSyx/submodel/api/qualifier/qualifiable/IConstraint.h>
-
-#include <string>
-
-namespace basyx {
-namespace submodel {
-
-class IQualifier 
-  : public virtual IHasSemantics
-  , public virtual IConstraint
-{
-public:
-  struct Path {
-    static constexpr char Qualifier[] = "qualifier";
-    static constexpr char QualifierType[] = "qualifierType";
-    static constexpr char QualifierValue[] = "qualifierValue";
-    static constexpr char QualifierValueID[] = "qualifierValueId";
-    static constexpr char Modeltype[] = "Qualifier";
-  };
-
-public:
-	virtual ~IQualifier() = default;
-
-	virtual std::string getQualifierType() const = 0;
-	virtual basyx::object getQualifierValue() const = 0;
-	virtual std::shared_ptr<IReference> getQualifierValueId() const = 0;
-};
-
-}
-}
-
-#endif
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/reference/IKey.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/reference/IKey.h
deleted file mode 100644
index 348a6d8..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/reference/IKey.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * IKey.h
- *
- *      Author: wendel
- */ 
-
-#ifndef BASYX_METAMODEL_IKey_H_
-#define BASYX_METAMODEL_IKey_H_
-
-
-#include <string>
-
-namespace basyx {
-namespace submodel {
-
-class IKey
-{
-public:
-  struct Path
-  {
-    static constexpr char Type[] = "type";
-    static constexpr char Local[] = "local";
-    static constexpr char Value[] = "value";
-    static constexpr char IdType[] = "idType";
-  };
-public:
-	virtual ~IKey() = 0;
-
-	virtual std::string getType() const = 0;
-	virtual bool isLocal() const = 0;
-	virtual std::string getValue() const = 0;
-	virtual std::string getidType() const = 0;
-};
-
-inline IKey::~IKey() = default;
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/reference/IReference.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/reference/IReference.h
deleted file mode 100644
index 85b4894..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/reference/IReference.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * IReference.h
- *
- *      Author: wendel
- */ 
-
-#ifndef BASYX_METAMODEL_IReference_H_
-#define BASYX_METAMODEL_IReference_H_
-
-
-#include <BaSyx/submodel/api/reference/IKey.h>
-#include <BaSyx/shared/types.h>
-
-namespace basyx {
-namespace submodel {
-
-class IReference
-{
-public:
-	struct Path {
-		static constexpr char DataSpecifications[] = "dataSpecificationReferences";
-		static constexpr char Parents[] = "parentReferences";
-		static constexpr char SemanticIds[] = "semanticIdReferences";
-		static constexpr char Qualifiers[] = "qualifierReferences";
-		static constexpr char ReferencePath[] = "semanticIdentifier";
-		static constexpr char Key[] = "keys";
-	};
-public:
-  virtual ~IReference() = default;
-
-  virtual const basyx::specificCollection_t<IKey> getKeys() const = 0;
-  virtual void setKeys(const basyx::specificCollection_t<IKey> & keys) = 0;
-};
-
-}
-}
-
-#endif
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/IDataElement.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/IDataElement.h
deleted file mode 100644
index ddc5142..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/IDataElement.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * IDataElement.h
- *
- *      Author: wendel
- */ 
-
-#ifndef BASYX_METAMODEL_IDATAELEMENT_H_
-#define BASYX_METAMODEL_IDATAELEMENT_H_
-
-
-#include <BaSyx/submodel/api/submodelelement/ISubmodelElement.h>
-
-namespace basyx {
-namespace submodel {
-
-class IDataElement : public virtual ISubmodelElement
-{
-public:
-  virtual ~IDataElement() = 0;
-};
-
-inline IDataElement::~IDataElement() = default;
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/IReferenceElement.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/IReferenceElement.h
deleted file mode 100644
index 6b36eca..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/IReferenceElement.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * IReferenceElement.h
- *
- *      Author: wendel
- */
-
-#ifndef BASYX_METAMODEL_IREFERENCEELEMENT_H_
-#define BASYX_METAMODEL_IREFERENCEELEMENT_H_
-
-#include <BaSyx/submodel/api/reference/IReference.h>
-#include <BaSyx/submodel/api/submodelelement/property/IProperty.h>
-
-namespace basyx {
-namespace submodel {
-
-class IReferenceElement
-{
-public:
-  struct Path
-  {
-    static constexpr char Modeltype[] = "ReferenceElement";
-  };
-
-public:
-  virtual ~IReferenceElement() = default;
-
-  virtual std::shared_ptr<IReference> getValue() const = 0;
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/IRelationshipElement.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/IRelationshipElement.h
deleted file mode 100644
index d647aa0..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/IRelationshipElement.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * IRelationshipElement.h
- *
- *      Author: wendel
- */ 
-
-#ifndef BASYX_METAMODEL_IRelationshipElement_H_
-#define BASYX_METAMODEL_IRelationshipElement_H_
-
-#include <BaSyx/submodel/api/reference/IReference.h>
-
-namespace basyx {
-namespace submodel {
-
-
-class IRelationshipElement
-{
-public:
-  struct Path
-  {
-    static constexpr char First[] = "first";
-    static constexpr char Second[] = "second";
-    static constexpr char ModelType[] = "RelationshipElement";
-  };
-public:
-  virtual ~IRelationshipElement() = default;
-
-  virtual void setFirst(const IReference & first) = 0;
-  virtual std::shared_ptr<IReference> getFirst() const = 0;
-
-  virtual void setSecond(const IReference & second) = 0;
-  virtual std::shared_ptr<IReference> getSecond() const = 0;
-};
-
-}
-}
-
-#endif
-
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/ISubmodelElement.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/ISubmodelElement.h
deleted file mode 100644
index 0176a1b..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/ISubmodelElement.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * ISubmodelElement.h
- *
- *      Author: wendel
- */ 
-
-#ifndef BASYX_METAMODEL_ISUBMODELELEMENT_H_
-#define BASYX_METAMODEL_ISUBMODELELEMENT_H_
-
-
-#include <BaSyx/submodel/api/IElement.h>
-#include <BaSyx/submodel/api/qualifier/IHasDataSpecification.h>
-#include <BaSyx/submodel/api/qualifier/IReferable.h>
-#include <BaSyx/submodel/api/qualifier/qualifiable/IQualifiable.h>
-#include <BaSyx/submodel/api/qualifier/IHasSemantics.h>
-#include <BaSyx/submodel/api/qualifier/IHasKind.h>
-
-namespace basyx {
-namespace submodel {
-
-class ISubmodelElement :
-//	public virtual IElement,
-	public virtual IHasDataSpecification, 
-	public virtual IReferable,
-	public virtual IQualifiable,
-	public virtual IHasSemantics,
-	public virtual IHasKind
-{
-public:
-	struct Path {
-		static constexpr char ModelType[] = "SubmodelElement";
-	};
-public:
-  virtual ~ISubmodelElement() = default;
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/ISubmodelElementCollection.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/ISubmodelElementCollection.h
deleted file mode 100644
index c344679..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/ISubmodelElementCollection.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * ISubmodelElementCollection.h
- *
- *      Author: wendel
- */ 
-
-#ifndef BASYX_METAMODEL_ISubmodelElementCollection_H_
-#define BASYX_METAMODEL_ISubmodelElementCollection_H_
-
-
-#include <BaSyx/submodel/api/submodelelement/ISubmodelElement.h>
-#include <BaSyx/shared/types.h>
-
-namespace basyx {
-namespace submodel {
-
-
-class ISubmodelElementCollection
-{
-public:
-  struct Path
-  {
-    static constexpr long serialVersionUID = 1L;
-    static constexpr char Ordered[] = "ordered";
-    static constexpr char AllowDuplicates[] = "allowDuplicates";
-    static constexpr char ModelType[] = "SubmodelElementCollection";
-  };
-public:
-  virtual ~ISubmodelElementCollection() = default;
-
- // virtual void setValue(const basyx::specificCollection_t<ISubmodelElement> & value) = 0;
-  virtual basyx::specificCollection_t<ISubmodelElement> getValue() const = 0;
-
-  //virtual void setOrdered(const bool & value) = 0;
-  virtual bool isOrdered() const = 0;
-
-  //virtual void setAllowDuplicates(const bool & value) = 0;
-  virtual bool isAllowDuplicates() const = 0;
-
-  //virtual void setElements(const basyx::specificMap_t<ISubmodelElement> & value) = 0;
-  virtual basyx::specificMap_t<ISubmodelElement> getElements() const = 0;
-};
-
-}
-}
-
-#endif
-
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/entity/IEntity.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/entity/IEntity.h
deleted file mode 100644
index 7362a8a..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/entity/IEntity.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * IDataElement.h
- *
- *      Author: wendel
- */ 
-
-#ifndef BASYX_METAMODEL_IENTITY_H_
-#define BASYX_METAMODEL_IENTITY_H_
-
-#include <BaSyx/submodel/api/submodelelement/ISubmodelElement.h>
-#include <BaSyx/submodel/api/reference/IReference.h>
-
-#include <BaSyx/shared/enums.h>
-
-namespace basyx {
-namespace submodel {
-
-class IEntity : public virtual ISubmodelElement
-{
-public:
-	struct Path {
-		static constexpr char EntityType[] = "entityType";
-	};
-public:
-	virtual ~IEntity() = 0;
-
-	virtual basyx::specificCollection_t<ISubmodelElement> getStatements() = 0;
-
-	virtual EntityType getEntityType() const = 0;
-
-	virtual std::shared_ptr<IReference> getAsset() const = 0;
-};
-
-inline IEntity::~IEntity() = default;
-
-}
-}
-
-#endif
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/langstring/ILangStringSet.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/langstring/ILangStringSet.h
deleted file mode 100644
index df8867b..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/langstring/ILangStringSet.h
+++ /dev/null
@@ -1,32 +0,0 @@
-#ifndef _ILANGSTRINGSET_H
-#define _ILANGSTRINGSET_H
-
-#include <string>
-
-namespace basyx {
-namespace submodel {
-
-class ILangStringSet
-{
-public:
-	struct Path {
-		static constexpr char Language[] = "language";
-		static constexpr char Text[] = "text";
-	};
-public: // Constructors / dtor
-	ILangStringSet() = default; 
-
-
-	virtual ~ILangStringSet() = 0;
-public:
-
-    virtual const std::string & getLangString(const std::string & languageCode) const = 0;
-	virtual void addLangString(const std::string & languageCode, const std::string & langString) = 0 ;
-};
-
-inline ILangStringSet::~ILangStringSet() = default;
-
-}
-}
-
-#endif /* _ILANGSTRINGSET_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/operation/IOperation.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/operation/IOperation.h
deleted file mode 100644
index ac3a267..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/operation/IOperation.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * IOperation.h
- *
- *      Author: wendel
- */
-
-#ifndef AAS_SUBMODELELEMENT_OPERATION_IOPERATION_
-#define AAS_SUBMODELELEMENT_OPERATION_IOPERATION_
-
-#include <BaSyx/submodel/api/IElement.h>
-#include <BaSyx/submodel/api/submodelelement/operation/IOperationVariable.h>
-
-#include <BaSyx/shared/object.h>
-#include <BaSyx/shared/types.h>
-
-#include <vector>
-
-namespace basyx {
-namespace submodel {
-
-class IOperation : public virtual ISubmodelElement
-{
-public:
-	struct Path {
-		static constexpr char Input[] = "in";
-		static constexpr char Output[] = "out";
-		static constexpr char Invokable[] = "invokable";
-		static constexpr char ModelType[] = "operation";
-	};
-public:
-  virtual basyx::specificCollection_t<IOperationVariable> getParameterTypes() const = 0;
-  virtual std::shared_ptr<IOperationVariable> getReturnType() const = 0;
-  virtual basyx::object getInvocable() const = 0;
-  virtual basyx::object invoke(basyx::object & parameters) const = 0;
-};
-
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/operation/IOperationVariable.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/operation/IOperationVariable.h
deleted file mode 100644
index e54d540..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/operation/IOperationVariable.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * IOperationVariable.h
- *
- *      Author: wendel
- */ 
-
-#ifndef BASYX_METAMODEL_IOperationVariable_H_
-#define BASYX_METAMODEL_IOperationVariable_H_
-
-
-#include <BaSyx/submodel/api/submodelelement/ISubmodelElement.h>
-
-#include <memory>
-
-namespace basyx {
-namespace submodel {
-
-class IOperationVariable : public virtual ISubmodelElement
-{
-public:
-	struct Path {
-		static constexpr char Type[] = "type";
-    static constexpr char ModelType[] = "OperationVariable";
-    static constexpr char Value[] = "value";
-	};
-public:
-	virtual ~IOperationVariable() = default;
-	virtual std::shared_ptr<ISubmodelElement> getValue() const = 0;
-	virtual std::string getType() const = 0;
-};
-
-}
-}
-
-#endif
-
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/property/ICollectionProperty.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/property/ICollectionProperty.h
deleted file mode 100644
index 56f2e5d..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/property/ICollectionProperty.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * ICollectionProperty.h
- *
- *      Author: wendel
- */
-
-#ifndef AAS_SUBMODELELEMENT_PROPERTY_ICOLLECTIONPROPERTY_
-#define AAS_SUBMODELELEMENT_PROPERTY_ICOLLECTIONPROPERTY_
-
-#include <BaSyx/submodel/api/submodelelement/property/IProperty.h>
-#include <BaSyx/shared/types.h>
-
-
-namespace basyx {
-namespace submodel {
-namespace submodelelement {
-namespace property {
-
-class ICollectionProperty
-{
-
-public:
-  virtual ~ICollectionProperty() = default;
-
-  virtual void set(const basyx::object::object_list_t & collection) const = 0;
-  virtual void add(const basyx::object & newValue) = 0;
-  virtual void remove(basyx::object & objectRef) = 0;
-  virtual basyx::object::object_list_t getElements() const = 0;
-  virtual int getElementCount() const = 0;
-};
-
-}
-}
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/property/IContainerProperty.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/property/IContainerProperty.h
deleted file mode 100644
index 10f9ff2..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/property/IContainerProperty.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * IContainernProperty.h
- *
- *      Author: wendel
- */
-
-#ifndef AAS_SUBMODELELEMENT_PROPERTY_ICONTAINERPROPERTY_
-#define AAS_SUBMODELELEMENT_PROPERTY_ICONTAINERPROPERTY_
-
-
-#include <BaSyx/submodel/api/submodelelement/property/IProperty.h>
-#include <BaSyx/shared/types.h>
-#include <BaSyx/aas/backend/vab/IVABElementContainer.h>
-
-
-namespace basyx {
-namespace submodel {
-namespace submodelelement {
-namespace property {
-
-class IContainerProperty : public IProperty, vab::IVABElementContainer
-{
-
-public:
-  virtual ~IContainerProperty() = default;
-
-};
-
-}
-}
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/property/IMapProperty.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/property/IMapProperty.h
deleted file mode 100644
index 22b6b87..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/property/IMapProperty.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * IMapProperty.h
- *
- *      Author: wendel
- */
-
-#ifndef AAS_SUBMODELELEMENT_PROPERTY_IMAPPROPERTY_
-#define AAS_SUBMODELELEMENT_PROPERTY_IMAPPROPERTY_
-
-
-#include <BaSyx/submodel/api/submodelelement/property/IProperty.h>
-#include <BaSyx/shared/types.h>
-
-
-namespace basyx {
-namespace submodel {
-namespace submodelelement {
-namespace property {
-
-class IMapProperty
-{
-
-public:
-  virtual ~IMapProperty() = default;
-
-  virtual basyx::object getValue(const std::string & key) const = 0;
-  virtual void put(const std::string & key, const basyx::object & value) const = 0;
-  virtual void set(const basyx::object::object_map_t & map) const = 0;
-  virtual basyx::object::object_list_t getKeys() const = 0;
-  virtual int getEntryCount() const = 0;
-  virtual void remove(const std::string & key) const = 0;
-
-};
-
-}
-}
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/property/IProperty.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/property/IProperty.h
deleted file mode 100644
index 994b601..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/property/IProperty.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * IProperty.h
- *
- *  Created on: 29.04.2018
- *      Author: kuhn, wendel
- */
-#ifndef API_IPROPERTY_H_
-#define API_IPROPERTY_H_
-
-#include <BaSyx/submodel/api/submodelelement/IDataElement.h>
-
-#include <BaSyx/shared/types.h>
-
-namespace basyx {
-namespace submodel {
-
-
-/* *********************************************************************************
- * Property interface
- * *********************************************************************************/
-class IProperty : public virtual IDataElement
-{
-public:
-	enum class PropertyType
-	{
-		Single, Collection, Map, Container
-	};
-public:
-	struct Path {
-		static constexpr char Value[] = "value";
-		static constexpr char ValueId[] = "valueId";
-		static constexpr char ValueType[] = "valueType";
-		static constexpr char ModelType[] = "Property";
-	};
-public:
-	virtual PropertyType getPropertyType() const = 0;
-
-	virtual void setValueId(const std::string & valueId) = 0;
-	virtual std::string getValueId() const = 0;
-};
-
-}
-}
-
-#endif /* API_IPROPERTY_H_ */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/property/ISingleProperty.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/property/ISingleProperty.h
deleted file mode 100644
index 885e9a3..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/property/ISingleProperty.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * ISingleProperty.h
- *
- *      Author: wendel
- */
-
-#ifndef AAS_SUBMODELELEMENT_PROPERTY_ISINGLEPROPERTY_
-#define AAS_SUBMODELELEMENT_PROPERTY_ISINGLEPROPERTY_
-
-
-#include <BaSyx/submodel/api/submodelelement/property/IProperty.h>
-#include <BaSyx/shared/types.h>
-
-
-namespace basyx {
-namespace submodel {
-
-class ISingleProperty : public virtual IProperty
-{
-public:
-	virtual ~ISingleProperty() = default;
-
-	virtual basyx::object get() const = 0;
-	virtual void set(const basyx::object & newValue) = 0;
-	virtual std::string getValueType() const = 0;
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/property/blob/IBlob.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/property/blob/IBlob.h
deleted file mode 100644
index 3fe95de..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/property/blob/IBlob.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * IBlob.h
- *
- *      Author: wendel
- */
-
-#ifndef BASYX_METAMODEL_IBlob_H_
-#define BASYX_METAMODEL_IBlob_H_
-
-#include <BaSyx/shared/types.h>
-
-#include <BaSyx/submodel/api/submodelelement/IDataElement.h>
-
-namespace basyx {
-namespace submodel {
-
-
-class IBlob
-	: public IDataElement
-{
-public:
-	struct Path
-	{
-		static constexpr char MIMEType[] = "mimeType";
-		static constexpr char Value[] = "value";
-		static constexpr char ModelType[] = "blob";
-	};
-public:
-	virtual ~IBlob() = default;
-
-	virtual const std::string & getValue() const = 0;
-	virtual const std::string & getMimeType() const = 0;
-};
-
-}
-}
-
-#endif
-
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/property/file/IFile.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/property/file/IFile.h
deleted file mode 100644
index b9a046c..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api/submodelelement/property/file/IFile.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * IFile.h
- *
- *      Author: wendel
- */ 
-
-#ifndef BASYX_METAMODEL_IFile_H_
-#define BASYX_METAMODEL_IFile_H_
-
-#include <string>
-
-namespace basyx {
-namespace submodel {
-
-class IFile
-{
-public:
-	struct Path
-	{
-		static constexpr char MIMEType[] = "mimeType";
-		static constexpr char Value[] = "value";
-		static constexpr char ModelType[] = "file";
-	};
-public:
-	virtual ~IFile() = default;
-
-	virtual const std::string & getValue() const = 0;
-	virtual const std::string & getMimeType() const = 0;
-};
-
-}
-}
-
-#endif
-
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/aas/IAssetAdministrationShell.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/aas/IAssetAdministrationShell.h
index 3e6df30..564fad2 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/aas/IAssetAdministrationShell.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/aas/IAssetAdministrationShell.h
@@ -38,5 +38,4 @@
 }
 }
 
-
 #endif /* BASYX_SUBMODEL_API_V2_AAS_IASSETADMINISTRATIONSHELL_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/common/IElementContainer.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/common/IElementContainer.h
index 945a030..0bcc6b2 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/common/IElementContainer.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/common/IElementContainer.h
@@ -2,6 +2,7 @@
 #define BASYX_SUBMODEL_API_V2_COMMON_IELEMENTCONTAINER_H
 
 #include <BaSyx/submodel/api_v2/submodelelement/ISubmodelElement.h>
+#include <BaSyx/submodel/api_v2/qualifier/IReferable.h>
 
 #include <BaSyx/util/util.h>
 
@@ -23,6 +24,7 @@
 	virtual IElementType * const getElement(const std::string & idShort) const = 0;
 	virtual IElementType * const getElement(std::size_t n) const = 0;
 
+	virtual IReferable * getParent() const = 0;
 	virtual void addElement(elementPtr_t element) = 0;
 
 	virtual std::size_t size() const = 0;
@@ -32,6 +34,7 @@
 	{
 		auto ptr = util::make_unique<SubElement_t>(std::forward<Args>(args)...);
 		auto ret = ptr.get();
+		ptr->setParent(this->getParent());
 		this->addElement(std::move(ptr));
 		return ret;
 	};
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/common/IModelType.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/common/IModelType.h
index 2e36d68..4d715c4 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/common/IModelType.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/common/IModelType.h
@@ -20,4 +20,4 @@
 }
 }
 
-#endif /* BASYX_SUBMODEL_API_V2_COMMON_IELEMENTCONTAINER_H */
+#endif /* BASYX_SUBMODEL_API_V2_COMMON_IMODELTYPE_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/constraint/IConstraint.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/constraint/IConstraint.h
index 9c84c09..269f461 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/constraint/IConstraint.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/constraint/IConstraint.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_SUBMODEL_API_V2_QUALIFIER_ICONSTRAINT_H
-#define BASYX_SUBMODEL_API_V2_QUALIFIER_ICONSTRAINT_H
+#ifndef BASYX_SUBMODEL_API_V2_CONSTRAINT_ICONSTRAINT_H
+#define BASYX_SUBMODEL_API_V2_CONSTRAINT_ICONSTRAINT_H
 
 #include <BaSyx/submodel/api_v2/common/IModelType.h>
 
@@ -20,4 +20,4 @@
 }
 }
 
-#endif /* BASYX_SUBMODEL_API_V2_QUALIFIER_ICONSTRAINT_H */
\ No newline at end of file
+#endif /* BASYX_SUBMODEL_API_V2_CONSTRAINT_ICONSTRAINT_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/constraint/IFormula.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/constraint/IFormula.h
index 4b15bf7..5d1bf67 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/constraint/IFormula.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/constraint/IFormula.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_SUBMODEL_API_V2_QUALIFIER_IFORMULA_H
-#define BASYX_SUBMODEL_API_V2_QUALIFIER_IFORMULA_H
+#ifndef BASYX_SUBMODEL_API_V2_CONSTRAINT_IFORMULA_H
+#define BASYX_SUBMODEL_API_V2_CONSTRAINT_IFORMULA_H
 
 #include <BaSyx/submodel/api_v2/constraint/IConstraint.h>
 #include <BaSyx/submodel/simple/reference/Reference.h>
@@ -26,4 +26,4 @@
 }
 }
 
-#endif /* BASYX_SUBMODEL_API_V2_QUALIFIER_IFORMULA_H */
\ No newline at end of file
+#endif /* BASYX_SUBMODEL_API_V2_CONSTRAINT_IFORMULA_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/constraint/IQualifier.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/constraint/IQualifier.h
index 6b08881..36da62a 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/constraint/IQualifier.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/constraint/IQualifier.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_SUBMODEL_API_V2_QUALIFIER_IQUALIFIER_H
-#define BASYX_SUBMODEL_API_V2_QUALIFIER_IQUALIFIER_H
+#ifndef BASYX_SUBMODEL_API_V2_CONSTRAINT_IQUALIFIER_H
+#define BASYX_SUBMODEL_API_V2_CONSTRAINT_IQUALIFIER_H
 
 #include <BaSyx/submodel/api_v2/constraint/IConstraint.h>
 #include <BaSyx/submodel/api_v2/qualifier/IHasSemantics.h>
@@ -36,4 +36,4 @@
 }
 }
 
-#endif /* BASYX_SUBMODEL_API_V2_QUALIFIER_IQUALIFIER_H */
\ No newline at end of file
+#endif /* BASYX_SUBMODEL_API_V2_CONSTRAINT_IQUALIFIER_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/dataspecification/IDataSpecification.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/dataspecification/IDataSpecification.h
index c84c7c3..1864f28 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/dataspecification/IDataSpecification.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/dataspecification/IDataSpecification.h
@@ -21,8 +21,12 @@
 	virtual ~IDataSpecification() = 0;
 
 	virtual IDataSpecificationContent & getContent() = 0;
+
+	virtual KeyElements getKeyElementType() const override;
 };
 
+inline KeyElements IDataSpecification::getKeyElementType() const { return KeyElements::DataElement; };
+
 inline IDataSpecification::~IDataSpecification() = default;
 
 }
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/dataspecification/IDataSpecificationIEC61360.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/dataspecification/IDataSpecificationIEC61360.h
index f53fa55..8b5cb60 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/dataspecification/IDataSpecificationIEC61360.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/dataspecification/IDataSpecificationIEC61360.h
@@ -50,4 +50,4 @@
 }
 }
 
-#endif /* BASYX_SUBMODEL_API_V2_DATASPECIFICATION_IDATASPECIFICATIONIEC61360_H */
\ No newline at end of file
+#endif /* BASYX_SUBMODEL_API_V2_DATASPECIFICATION_IDATASPECIFICATIONIEC61360_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/dataspecification/IDataSpecificationPhysicalUnit.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/dataspecification/IDataSpecificationPhysicalUnit.h
index 19b29f1..bac90b3 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/dataspecification/IDataSpecificationPhysicalUnit.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/dataspecification/IDataSpecificationPhysicalUnit.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_API_V2_SDK_IDATASPECIFICATIONPHYSICALUNIT_H
-#define BASYX_API_V2_SDK_IDATASPECIFICATIONPHYSICALUNIT_H
+#ifndef BASYX_SUBMODEL_API_V2_DATASPECIFICATION_IDATASPECIFICATIONPHYSICALUNIT_H
+#define BASYX_SUBMODEL_API_V2_DATASPECIFICATION_IDATASPECIFICATIONPHYSICALUNIT_H
 
 #include <string>
 
@@ -64,4 +64,4 @@
 }
 }
 }
-#endif //BASYX_API_V2_SDK_IDATASPECIFICATIONPHYSICALUNIT_H
+#endif /* BASYX_SUBMODEL_API_V2_DATASPECIFICATION_IDATASPECIFICATIONPHYSICALUNIT_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/dataspecification/IEmbeddedDataSpecification.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/dataspecification/IEmbeddedDataSpecification.h
index 1f5b8b7..cdf0927 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/dataspecification/IEmbeddedDataSpecification.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/dataspecification/IEmbeddedDataSpecification.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_API_V2_SDK_IEMBEDDEDDATASPECIFICATION_H
-#define BASYX_API_V2_SDK_IEMBEDDEDDATASPECIFICATION_H
+#ifndef BASYX_SUBMODEL_API_V2_DATASPECIFICATION_IEMBEDDEDDATASPECIFICATION_H
+#define BASYX_SUBMODEL_API_V2_DATASPECIFICATION_IEMBEDDEDDATASPECIFICATION_H
 
 #include <BaSyx/submodel/api_v2/reference/IReference.h>
 
@@ -20,4 +20,4 @@
 }
 }
 }
-#endif //BASYX_API_V2_SDK_IEMBEDDEDDATASPECIFICATION_H
+#endif /* BASYX_SUBMODEL_API_V2_DATASPECIFICATION_IEMBEDDEDDATASPECIFICATION_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/dataspecification/IValueList.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/dataspecification/IValueList.h
index 884f9ed..ee79691 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/dataspecification/IValueList.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/dataspecification/IValueList.h
@@ -22,4 +22,4 @@
 }
 }
 
-#endif
\ No newline at end of file
+#endif /* BASYX_SUBMODEL_API_V2_DATASPECIFICATION_IVALUELIST_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/parts/IConceptDictionary.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/parts/IConceptDictionary.h
index e09715e..b9a0208 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/parts/IConceptDictionary.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/parts/IConceptDictionary.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_API_V2_SDK_ICONCEPTDICTIONARY_H
-#define BASYX_API_V2_SDK_ICONCEPTDICTIONARY_H
+#ifndef BASYX_SUBMODEL_API_V2_PARTS_ICONCEPTDICTIONARY_H
+#define BASYX_SUBMODEL_API_V2_PARTS_ICONCEPTDICTIONARY_H
 
 #include <BaSyx/submodel/api_v2/parts/IConceptDescription.h>
 
@@ -21,4 +21,4 @@
 }
 }
 }
-#endif //BASYX_API_V2_SDK_ICONCEPTDICTIONARY_H
+#endif /* BASYX_SUBMODEL_API_V2_PARTS_ICONCEPTDICTIONARY_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/parts/IView.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/parts/IView.h
index bedbb41..88e3d51 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/parts/IView.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/parts/IView.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_API_V2_SDK_IVIEW_H
-#define BASYX_API_V2_SDK_IVIEW_H
+#ifndef BASYX_SUBMODEL_API_V2_PARTS_IVIEW_H
+#define BASYX_SUBMODEL_API_V2_PARTS_IVIEW_H
 
 #include <BaSyx/submodel/api_v2/qualifier/IReferable.h>
 #include <BaSyx/submodel/api_v2/qualifier/IHasDataSpecification.h>
@@ -26,4 +26,4 @@
 }
 }
 }
-#endif //BASYX_API_V2_SDK_IVIEW_H
+#endif /* BASYX_SUBMODEL_API_V2_PARTS_IVIEW_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/qualifier/IAdministrativeInformation.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/qualifier/IAdministrativeInformation.h
new file mode 100644
index 0000000..c659d45
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/qualifier/IAdministrativeInformation.h
@@ -0,0 +1,33 @@
+#ifndef BASYX_SUBMODEL_API_V2_QUALIFIER_IADMINISTRATIVEINFORMATION_H
+#define BASYX_SUBMODEL_API_V2_QUALIFIER_IADMINISTRATIVEINFORMATION_H
+
+#include <BaSyx/submodel/api_v2/qualifier/IHasDataSpecification.h>
+
+#include <string>
+
+namespace basyx {
+namespace submodel {
+namespace api {
+
+class IAdministrativeInformation
+  : public virtual IHasDataSpecification
+{
+public:
+  virtual ~IAdministrativeInformation() = 0;
+
+  virtual void setVersion(const std::string & version) = 0;
+  virtual void setRevision(const std::string & revision) = 0;
+
+  virtual bool hasVersion() const = 0;
+  virtual bool hasRevision() const = 0;
+
+  virtual const std::string * const getVersion() const = 0;
+  virtual const std::string * const getRevision() const = 0;
+};
+
+inline IAdministrativeInformation::~IAdministrativeInformation() = default;
+
+}
+}
+}
+#endif /* BASYX_SUBMODEL_API_V2_QUALIFIER_IADMINISTRATIVEINFORMATION_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/qualifier/IHasDataSpecification.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/qualifier/IHasDataSpecification.h
index 9b8af08..c826aa6 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/qualifier/IHasDataSpecification.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/qualifier/IHasDataSpecification.h
@@ -1,12 +1,13 @@
 #ifndef BASYX_SUBMODEL_API_V2_QUALIFIER_IHASDATASPECIFICATION_H
 #define BASYX_SUBMODEL_API_V2_QUALIFIER_IHASDATASPECIFICATION_H
 
-#include <BaSyx/submodel/simple/reference/Reference.h>
-
 #include <vector>
 
 namespace basyx {
 namespace submodel {
+
+namespace simple { class Reference; }
+
 namespace api {
 
 class IHasDataSpecification
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/qualifier/IIdentifiable.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/qualifier/IIdentifiable.h
index 361d494..9eaebfe 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/qualifier/IIdentifiable.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/qualifier/IIdentifiable.h
@@ -1,19 +1,16 @@
 #ifndef BASYX_SUBMODEL_API_V2_QUALIFIER_IIDENTIFIABLE_H
 #define BASYX_SUBMODEL_API_V2_QUALIFIER_IIDENTIFIABLE_H
 
-#include <BaSyx/submodel/simple/identifier/Identifier.h>
-//#include <BaSyx/submodel/api_v2/qualifier/IAdministrativeInformation.h>
-
 #include <BaSyx/submodel/api_v2/qualifier/IReferable.h>
+#include <BaSyx/submodel/api_v2/qualifier/IAdministrativeInformation.h>
+#include <BaSyx/submodel/simple/identifier/Identifier.h>
+
 
 #include <string>
 #include <memory>
 
 namespace basyx {
 namespace submodel {
-
-namespace simple { class AdministrativeInformation; }
-
 namespace api {
 
 class IIdentifiable : public virtual IReferable
@@ -21,12 +18,16 @@
 public:
   virtual ~IIdentifiable() = 0;
 
-  virtual const simple::AdministrativeInformation & getAdministrativeInformation() const = 0;
-  virtual simple::AdministrativeInformation & getAdministrativeInformation() = 0;
+  virtual const IAdministrativeInformation & getAdministrativeInformation() const = 0;
+  virtual IAdministrativeInformation & getAdministrativeInformation() = 0;
 
   virtual simple::Identifier getIdentification() const = 0;
 
   virtual bool hasAdministrativeInformation() const = 0;
+
+  virtual KeyType getKeyType() const {
+	  return this->getIdentification().getIdType();
+  };
 };
 
 inline IIdentifiable::~IIdentifiable() = default;
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/qualifier/IQualifiable.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/qualifier/IQualifiable.h
index 45ea82c..2687fe1 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/qualifier/IQualifiable.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/qualifier/IQualifiable.h
@@ -2,17 +2,20 @@
 #define BASYX_SUBMODEL_API_V2_QUALIFIER_IQUALIFIABLE_H
 
 #include <BaSyx/submodel/api_v2/constraint/IFormula.h>
-#include <BaSyx/submodel/api_v2/constraint/IQualifier.h>
 
 #include <BaSyx/submodel/simple/constraint/Formula.h>
-#include <BaSyx/submodel/simple/constraint/Qualifier.h>
 
 #include <vector>
 
 namespace basyx {
 namespace submodel {
+
+namespace simple { class Qualifier; }
+
 namespace api {
 
+class IQualifier;
+
 class IQualifiable
 {
 public:
@@ -31,4 +34,4 @@
 }
 }
 
-#endif /* BASYX_SUBMODEL_API_V2_QUALIFIER_IQUALIFIABLE_H */
\ No newline at end of file
+#endif /* BASYX_SUBMODEL_API_V2_QUALIFIER_IQUALIFIABLE_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/qualifier/IReferable.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/qualifier/IReferable.h
index 41b9f3b..7be8daf 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/qualifier/IReferable.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/qualifier/IReferable.h
@@ -3,6 +3,7 @@
 
 #include <BaSyx/submodel/api_v2/reference/IReference.h>
 #include <BaSyx/submodel/api_v2/common/ILangStringSet.h>
+#include <BaSyx/submodel/simple/reference/Reference.h>
 
 #include <string>
 #include <memory>
@@ -14,7 +15,7 @@
 /**
  * Mandatory members:
  *    idShort
- *
+ *	
  */
 class IReferable
 {
@@ -26,7 +27,16 @@
 	virtual void setCategory(const std::string & category) = 0;
 	virtual ILangStringSet & getDescription() = 0;
 	virtual const ILangStringSet & getDescription() const = 0;
-	virtual const IReferable * const getParent() const = 0;
+	virtual IReferable * getParent() const = 0;
+	virtual void setParent(IReferable * parent) = 0;
+	virtual simple::Reference getReference() const = 0;
+	virtual simple::Key getKey(bool local = true) const = 0;
+
+	virtual KeyElements getKeyElementType() const = 0;
+
+	virtual KeyType getKeyType() const {
+		return KeyType::IdShort;
+	};
 };
 
 inline IReferable::~IReferable() = default;
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/IAnnotatedRelationshipElement.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/IAnnotatedRelationshipElement.h
index da9a4a7..578175e 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/IAnnotatedRelationshipElement.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/IAnnotatedRelationshipElement.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_API_V2_SDK_IANNOTATEDRELATIONSHIPELEMENT_H
-#define BASYX_API_V2_SDK_IANNOTATEDRELATIONSHIPELEMENT_H
+#ifndef BASYX_SUBMODEL_API_V2_SUBMODELELEMENT_IANNOTATEDRELATIONSHIPELEMENT_H
+#define BASYX_SUBMODEL_API_V2_SUBMODELELEMENT_IANNOTATEDRELATIONSHIPELEMENT_H
 
 #include <BaSyx/submodel/api_v2/submodelelement/IDataElement.h>
 #include <BaSyx/submodel/api_v2/common/IElementContainer.h>
@@ -8,12 +8,14 @@
 namespace submodel {
 namespace api {
 
-class IAnnotatedRelationshipElement
+class IAnnotatedRelationshipElement : public IDataElement
 {
 public:
   virtual ~IAnnotatedRelationshipElement() = 0;
 
   virtual IElementContainer<IDataElement> & getAnnotation() const = 0;
+
+  virtual KeyElements getKeyElementType() const override { return KeyElements::AnnotatedRelationshipElement; };
 };
 
 inline IAnnotatedRelationshipElement::~IAnnotatedRelationshipElement() = default;
@@ -21,4 +23,4 @@
 }
 }
 }
-#endif //BASYX_API_V2_SDK_IANNOTATEDRELATIONSHIPELEMENT_H
+#endif /* BASYX_SUBMODEL_API_V2_SUBMODELELEMENT_IANNOTATEDRELATIONSHIPELEMENT_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/IBasicEvent.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/IBasicEvent.h
index ffbc11a..fe9f5c4 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/IBasicEvent.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/IBasicEvent.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_API_V2_SDK_IBASICEVENT_H
-#define BASYX_API_V2_SDK_IBASICEVENT_H
+#ifndef BASYX_SUBMODEL_API_V2_SUBMODELELEMENT_IBASICEVENT_H
+#define BASYX_SUBMODEL_API_V2_SUBMODELELEMENT_IBASICEVENT_H
 
 #include <BaSyx/submodel/api_v2/submodelelement/IBasicEvent.h>
 
@@ -21,4 +21,4 @@
 }
 }
 }
-#endif //BASYX_API_V2_SDK_IBASICEVENT_H
+#endif /* BASYX_SUBMODEL_API_V2_SUBMODELELEMENT_IBASICEVENT_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/ICapability.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/ICapability.h
index 157f4e0..7653ef2 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/ICapability.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/ICapability.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_API_V2_SDK_ICAPABILITY_H
-#define BASYX_API_V2_SDK_ICAPABILITY_H
+#ifndef BASYX_SUBMODEL_API_V2_SUBMODELELEMENT_ICAPABILITY_H
+#define BASYX_SUBMODEL_API_V2_SUBMODELELEMENT_ICAPABILITY_H
 
 #include <BaSyx/submodel/api_v2/submodelelement/ISubmodelElement.h>
 
@@ -12,6 +12,8 @@
 {
 public:
   ~ICapability() = 0;
+
+  virtual KeyElements getKeyElementType() const override { return KeyElements::Capability; };
 };
 
 inline ICapability::~ICapability() = default;
@@ -19,4 +21,4 @@
 }
 }
 }
-#endif //BASYX_API_V2_SDK_ICAPABILITY_H
+#endif /* BASYX_SUBMODEL_API_V2_SUBMODELELEMENT_ICAPABILITY_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/IDataElement.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/IDataElement.h
index 0ff489c..9a1cce5 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/IDataElement.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/IDataElement.h
@@ -12,6 +12,8 @@
 {
 public:
   virtual ~IDataElement() = 0;
+
+  virtual KeyElements getKeyElementType() const override { return KeyElements::DataElement; };
 };
 
 inline IDataElement::~IDataElement() = default;
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/IEntity.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/IEntity.h
index 905e1f4..cd262ec 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/IEntity.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/IEntity.h
@@ -22,6 +22,8 @@
 
 	virtual const IReference * const getAssetRef() const = 0;
 	virtual void setAssetRef(const IReference & assetRef) = 0;
+
+	virtual KeyElements getKeyElementType() const override { return KeyElements::Entity; };
 };
 
 inline IEntity::~IEntity() = default;
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/IEvent.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/IEvent.h
index 762f1f3..6a0836d 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/IEvent.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/IEvent.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_API_V2_SDK_IEVENT_H
-#define BASYX_API_V2_SDK_IEVENT_H
+#ifndef BASYX_SUBMODEL_API_V2_SUBMODELELEMENT_IEVENT_H
+#define BASYX_SUBMODEL_API_V2_SUBMODELELEMENT_IEVENT_H
 
 #include <BaSyx/submodel/api_v2/submodelelement/ISubmodelElement.h>
 
@@ -12,6 +12,8 @@
 {
 public:
   ~IEvent() = 0;
+
+  virtual KeyElements getKeyElementType() const override { return KeyElements::Event; };
 };
 
 inline IEvent::~IEvent() = default;
@@ -19,4 +21,4 @@
 }
 }
 }
-#endif //BASYX_API_V2_SDK_IEVENT_H
+#endif /* BASYX_SUBMODEL_API_V2_SUBMODELELEMENT_IEVENT_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/IRange.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/IRange.h
index b452584..b5b9fb9 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/IRange.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/IRange.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_API_V2_SDK_IRANGE_H
-#define BASYX_API_V2_SDK_IRANGE_H
+#ifndef BASYX_SUBMODEL_API_V2_SUBMODELELEMENT_IRANGE_H
+#define BASYX_SUBMODEL_API_V2_SUBMODELELEMENT_IRANGE_H
 
 #include <string>
 
@@ -28,6 +28,8 @@
 
   virtual ValueDataType getMin() = 0;
   virtual ValueDataType getMax() = 0;
+
+  virtual KeyElements getKeyElementType() const override { return KeyElements::Range; };
 };
 
 inline IRange::~IRange() = default;
@@ -35,4 +37,4 @@
 }
 }
 }
-#endif //BASYX_API_V2_SDK_IRANGE_H
+#endif /* BASYX_SUBMODEL_API_V2_SUBMODELELEMENT_IRANGE_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/IRelationshipElement.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/IRelationshipElement.h
index 39b7774..4c21018 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/IRelationshipElement.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/IRelationshipElement.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_API_V2_SDK_IRELATIONSHIPELEMENT_H
-#define BASYX_API_V2_SDK_IRELATIONSHIPELEMENT_H
+#ifndef BASYX_SUBMODEL_API_V2_SUBMODELELEMENT_IRELATIONSHIPELEMENT_H
+#define BASYX_SUBMODEL_API_V2_SUBMODELELEMENT_IRELATIONSHIPELEMENT_H
 
 #include <BaSyx/submodel/api_v2/submodelelement/ISubmodelElement.h>
 
@@ -18,6 +18,8 @@
 
   virtual IReferable & getFirst() const = 0;
   virtual IReferable & getSecond() const = 0;
+
+  virtual KeyElements getKeyElementType() const override { return KeyElements::RelationshipElement; };
 };
 
 inline IRelationshipElement::~IRelationshipElement() = default;
@@ -25,4 +27,4 @@
 }
 }
 }
-#endif //BASYX_API_V2_SDK_IRELATIONSHIPELEMENT_H
+#endif /* BASYX_SUBMODEL_API_V2_SUBMODELELEMENT_IRELATIONSHIPELEMENT_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/ISubmodelElement.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/ISubmodelElement.h
index c908a29..e6a6bad 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/ISubmodelElement.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/ISubmodelElement.h
@@ -1,6 +1,7 @@
 #ifndef BASYX_SUBMODEL_API_V2_SUBMODELELEMENT_ISUBMODELELEMENT_H
 #define BASYX_SUBMODEL_API_V2_SUBMODELELEMENT_ISUBMODELELEMENT_H
 
+#include <BaSyx/submodel/api_v2/qualifier/IQualifiable.h>
 #include <BaSyx/submodel/api_v2/qualifier/IHasDataSpecification.h>
 #include <BaSyx/submodel/api_v2/qualifier/IHasSemantics.h>
 #include <BaSyx/submodel/api_v2/qualifier/IReferable.h>
@@ -8,17 +9,18 @@
 #include <BaSyx/submodel/api_v2/common/IModelType.h>
 
 
+
 namespace basyx {
 namespace submodel {
 namespace api {
 
-class ISubmodelElement :
-	public virtual IHasDataSpecification, 
-	public virtual IReferable,
-//	public virtual IQualifiable,
-	public virtual IHasSemantics,
-	public virtual IHasKind,
-	public virtual IModelType
+class ISubmodelElement
+  : public virtual IHasDataSpecification
+  , public virtual IReferable
+  , public virtual IHasSemantics
+  , public virtual IQualifiable
+  , public virtual IHasKind
+  ,	public virtual IModelType
 {
 public:
   virtual ~ISubmodelElement() = 0;
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/file/IBlob.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/file/IBlob.h
index 08044a8..b4435e8 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/file/IBlob.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/file/IBlob.h
@@ -27,6 +27,8 @@
 
 	virtual const MimeType getMimeType() const = 0;
 	virtual void setMimeType(const MimeType & mimeType) = 0;
+
+	virtual KeyElements getKeyElementType() const override { return KeyElements::Blob; };
 };
 
 inline IBlob::~IBlob() = default;
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/file/IFile.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/file/IFile.h
index 75fc4f6..88ad38f 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/file/IFile.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/file/IFile.h
@@ -24,6 +24,8 @@
 
 	virtual const MimeType getMimeType() const = 0;
 	virtual void setMimeType(const MimeType & mimeType) = 0;
+
+	virtual KeyElements getKeyElementType() const override { return KeyElements::File; };
 };
 
 inline IFile::~IFile() = default;
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/operation/IOperationVariable.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/operation/IOperationVariable.h
index 6204374..37a589c 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/operation/IOperationVariable.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/operation/IOperationVariable.h
@@ -16,6 +16,8 @@
 	virtual ~IOperationVariable() = 0;
 
 	virtual ISubmodelElement & getValue() const = 0;
+
+	virtual KeyElements getKeyElementType() const override { return KeyElements::OperationVariable; };
 };
 
 inline IOperationVariable::~IOperationVariable() = default;
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/property/XSDAnySimpleType.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/property/XSDAnySimpleType.h
new file mode 100644
index 0000000..f77885f
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/submodelelement/property/XSDAnySimpleType.h
@@ -0,0 +1,666 @@
+#ifndef BASYX_C_SDK_XSDANYSIMPLETYPE_H
+#define BASYX_C_SDK_XSDANYSIMPLETYPE_H
+
+#include <string>
+#include <ctime>
+#include <chrono>
+#include <iomanip>
+#include <regex>
+
+#include <BaSyx/submodel/simple/common/xsd_types/AnyURI.h>
+#include <BaSyx/submodel/simple/common/xsd_types/DateTime.h>
+#include <BaSyx/submodel/simple/common/xsd_types/Date.h>
+#include <BaSyx/submodel/simple/common/xsd_types/DayTimeDuration.h>
+#include <BaSyx/submodel/simple/common/xsd_types/YearMonthDuration.h>
+#include <BaSyx/submodel/simple/common/xsd_types/Time.h>
+#include <BaSyx/submodel/simple/common/xsd_types/GYearMonth.h>
+#include <BaSyx/submodel/simple/common/xsd_types/GYear.h>
+#include <BaSyx/submodel/simple/common/xsd_types/GMonthDay.h>
+#include <BaSyx/submodel/simple/common/xsd_types/GDay.h>
+#include <BaSyx/submodel/simple/common/xsd_types/GMonth.h>
+#include <sstream>
+
+
+namespace basyx {
+namespace xsd_types {
+using namespace submodel;
+
+  static const std::string getPrimitiveXSDType(type::valueType type)
+  {
+    switch(type)
+    {
+      case type::valueType::Bool:
+        return "boolean";
+      case type::valueType::Int:
+        return "integer";
+      case type::valueType::Float:
+        return "float";
+      case type::valueType::String:
+        return "string";
+      default:
+        return "Type not supported!";
+    }
+  }
+
+  template<typename T, typename Enable = void>
+  struct xsd_type
+  {
+    static constexpr int fail_vab_type_not_supported() { static_assert("Type not supported by VAB!"); return 0; };
+    static const std::string getDataTypeDef()
+    {
+      return "Not supported!";
+    };
+  };
+
+  template<>
+  struct xsd_type<bool>
+  {
+    static const std::string getDataTypeDef()
+    {
+      return "boolean";
+    }
+
+    static const inline bool getXSDRepresentation(const bool & bool_value)
+    {
+      return bool_value;
+    }
+
+    static const inline bool fromXSDRepresentation(basyx::object value)
+    {
+      return value.Get<bool>();
+    }
+  };
+
+  template<>
+  struct xsd_type<int>
+  {
+    static const std::string getDataTypeDef()
+    {
+      return "integer";
+    }
+
+    static const inline int getXSDRepresentation(const int & int_value)
+    {
+      return int_value;
+    }
+
+    static const inline int fromXSDRepresentation(basyx::object value)
+    {
+      return value.Get<int>();
+    }
+  };
+
+template<>
+  struct xsd_type<long>
+  {
+    static const std::string getDataTypeDef()
+    {
+      return "long";
+    }
+
+    static const inline long getXSDRepresentation(const long & long_value)
+    {
+      return long_value;
+    }
+
+    static const inline long fromXSDRepresentation(basyx::object value)
+    {
+      return value.Get<long>();
+    }
+  };
+
+  template<>
+  struct xsd_type<short>
+  {
+    static const std::string getDataTypeDef()
+    {
+      return "short";
+    }
+
+    static const inline short getXSDRepresentation(const short & short_value)
+    {
+      return short_value;
+    }
+
+    static const inline short fromXSDRepresentation(basyx::object value)
+    {
+      return value.Get<short>();
+    }
+  };
+
+  template<>
+  struct xsd_type<unsigned int>
+  {
+    static const std::string getDataTypeDef()
+    {
+      return "unsignedInt";
+    }
+
+    static const inline unsigned int getXSDRepresentation(const unsigned int & uint_value)
+    {
+      return uint_value;
+    }
+
+    static const inline unsigned int fromXSDRepresentation(basyx::object value)
+    {
+      return value.Get<unsigned int>();
+    }
+  };
+
+  template<>
+  struct xsd_type<unsigned short>
+  {
+    static const std::string getDataTypeDef()
+    {
+      return "unsignedShort";
+    }
+
+    static const inline unsigned short getXSDRepresentation(const unsigned short & ushort_value)
+    {
+      return ushort_value;
+    }
+
+    static const inline unsigned short fromXSDRepresentation(basyx::object value)
+    {
+      return value.Get<unsigned short>();
+    }
+  };
+
+  template<>
+  struct xsd_type<unsigned long>
+  {
+    static const std::string getDataTypeDef()
+    {
+      return "unsignedLong";
+    }
+
+    static const inline unsigned long getXSDRepresentation(const unsigned long & ulong_value)
+    {
+      return ulong_value;
+    }
+
+    static const inline unsigned long fromXSDRepresentation(basyx::object value)
+    {
+      return value.Get<unsigned long>();
+    }
+  };
+
+  template<>
+  struct xsd_type<double>
+  {
+    static const std::string getDataTypeDef()
+    {
+      return "double";
+    }
+
+    static const inline double getXSDRepresentation(const double & double_value)
+    {
+      return double_value;
+    }
+
+    static const inline double fromXSDRepresentation(basyx::object value)
+    {
+      return value.Get<double>();
+    }
+  };
+
+  template<>
+  struct xsd_type<float>
+  {
+    static const std::string getDataTypeDef()
+    {
+      return "float";
+    }
+
+    static const inline float getXSDRepresentation(const float & float_value)
+    {
+      return float_value;
+    }
+
+    static const inline float fromXSDRepresentation(basyx::object value)
+    {
+      return value.Get<float>();
+    }
+  };
+
+  template<>
+  struct xsd_type<std::string>
+  {
+    static const std::string getDataTypeDef()
+    {
+      return "string";
+    }
+
+    static const inline std::string getXSDRepresentation(const std::string & string)
+    {
+      return string;
+    }
+
+    static const inline std::string fromXSDRepresentation(basyx::object value)
+    {
+      return value.GetStringContent();
+    }
+  };
+
+  template<>
+  struct xsd_type<simple::AnyURI>
+  {
+    static const std::string getDataTypeDef()
+    {
+      return "anyURI";
+    }
+
+    static const inline std::string getXSDRepresentation(const simple::AnyURI & uri)
+    {
+      return uri.getUri();
+    }
+
+    static const inline simple::AnyURI fromXSDRepresentation(const std::string & value)
+    {
+      return value;
+    }
+  };
+
+  template<>
+  struct xsd_type<simple::Date>
+  {
+    static constexpr char format[] = "%Y-%m-%dZ";
+
+    static const std::string getDataTypeDef()
+    {
+      return "date";
+    }
+
+    static const inline std::string getXSDRepresentation(const simple::Date & date)
+    {
+      std::stringstream formatted;
+      formatted << std::put_time(&date.getDate(), format);
+
+      return formatted.str();
+    }
+
+    static const inline simple::Date fromXSDRepresentation(basyx::object value)
+    {
+      tm date;
+      // Daylight Saving  is not in effect
+      date.tm_isdst = 0;
+
+      std::stringstream sstream;
+      sstream << value.GetStringContent();
+      sstream >> std::get_time(&date, format);
+
+      return simple::Date{date};
+    }
+  };
+
+  template<>
+  struct xsd_type<simple::DateTime>
+  {
+    static constexpr char format[] = "%Y-%m-%dT%TZ";
+
+    static const std::string getDataTypeDef()
+    {
+      return "dateTime";
+    }
+
+    static const inline std::string getXSDRepresentation(const simple::DateTime & dateTime)
+    {
+      std::stringstream formatted;
+      formatted << std::put_time(&dateTime.getTime(), format);
+
+      return formatted.str();
+    }
+
+    static const inline simple::DateTime fromXSDRepresentation(basyx::object value)
+    {
+      tm time;
+      // Daylight Saving Time is not in effect
+      time.tm_isdst = 0;
+
+      std::stringstream sstream;
+      sstream << value.GetStringContent();
+      sstream >> std::get_time(&time, format);
+
+      return simple::DateTime{time};
+    }
+  };
+
+  template<>
+  struct xsd_type<simple::DayTimeDuration>
+  {
+    static constexpr int seconds_per_day = 86400; //60*60*24
+    static constexpr int seconds_per_hour = 3600; //60*60
+    static constexpr int seconds_per_minute = 60;
+
+    static const std::string getDataTypeDef()
+    {
+      return "dayTimeDuration";
+    }
+
+    static const inline std::string getXSDRepresentation(const simple::DayTimeDuration & dayTimeDuration)
+    {
+      std::string xsd_str;
+      long duration = dayTimeDuration.getDuration().count();
+      if (duration < 0)
+      {
+        xsd_str = "-";
+        duration *= -1;
+      }
+      
+      xsd_str += "P";
+      if (duration / seconds_per_day)
+      {
+        xsd_str += std::to_string(duration / seconds_per_day) + "D";
+        duration = duration % seconds_per_day;
+      }
+      if (duration / seconds_per_hour)
+      {
+        xsd_str += std::to_string(duration / seconds_per_hour) + "H";
+        duration = duration % seconds_per_hour;
+      }
+      if (duration / seconds_per_minute)
+      {
+        xsd_str += std::to_string(duration / seconds_per_minute) + "M";
+        duration = duration % seconds_per_minute;
+      }
+      if (duration)
+        xsd_str += std::to_string(duration) + "S";
+
+      return xsd_str;
+    }
+
+    static const inline simple::DayTimeDuration fromXSDRepresentation(basyx::object value)
+    {
+      std::string xsd_str = value.GetStringContent();
+
+      long seconds = 0;
+
+      std::smatch match;
+      std::regex regex("\\d+D");
+      if (std::regex_search(xsd_str, match, regex))
+        seconds += std::stol(match.str()) * seconds_per_day;
+      regex = "\\d+H";
+      if (std::regex_search(xsd_str, match, regex))
+        seconds += std::stol(match.str()) * seconds_per_hour;
+      regex = "\\d+M";
+      if (std::regex_search(xsd_str, match, regex))
+        seconds += std::stol(match.str()) * seconds_per_minute;
+      regex = "\\d+S";
+      if (std::regex_search(xsd_str, match, regex))
+        seconds += std::stol(match.str());
+
+      if (xsd_str.find('-') == 0)
+        seconds *= -1;
+
+      return simple::DayTimeDuration{std::chrono::duration<long>(seconds)};
+    }
+  };
+
+
+  template<>
+  struct xsd_type<simple::YearMonthDuration>
+  {
+    static const std::string getDataTypeDef()
+    {
+      return "yearMonthDuration";
+    }
+
+    static const inline std::string getXSDRepresentation(const simple::YearMonthDuration & yearMonthDuration)
+    {
+      std::string xsd_str;
+      int years = yearMonthDuration.getYears();
+      int months = yearMonthDuration.getMonths();
+      if (years < 0)
+      {
+        xsd_str += "-";
+        years *= -1;
+      } else if (months < 0 and years == 0)
+      {
+        xsd_str += "-";
+        months *= -1;
+      }
+
+      xsd_str +=  "P";
+      xsd_str += (years > 0) ? std::to_string(years) + "Y" : "";
+      xsd_str += (months > 0) ? std::to_string(months) + "M" : "";
+
+      return xsd_str;
+    }
+
+    static const inline simple::YearMonthDuration fromXSDRepresentation(basyx::object value)
+    {
+      std::string xsd_str = value.GetStringContent();
+
+      int years = 0, months = 0;
+
+      std::smatch match;
+      std::regex regex("\\d+Y");
+      if (std::regex_search(xsd_str, match, regex))
+        years = std::stoi(match.str());
+      regex = "\\d+M";
+      if (std::regex_search(xsd_str, match, regex))
+        months = std::stoi(match.str());
+
+      if (xsd_str.find('-') == 0)
+        (years == 0) ? months *= -1 : years *= -1;
+
+      simple::YearMonthDuration yearMonthDuration{years,months};
+
+      return yearMonthDuration;
+    }
+  };
+
+  template<>
+  struct xsd_type<simple::Time>
+  {
+    static const std::string getDataTypeDef()
+    {
+      return "time";
+    }
+
+    static const inline std::string getXSDRepresentation(const simple::Time & time)
+    {
+      char buffer[9];
+      snprintf(buffer, 9, "%02d:%02d:%02d", time.getHours(), time.getMinutes(), int(time.getSeconds()));
+      std::string xsd_str{buffer};
+
+      // check if number has decimal places
+      if (std::fmod(time.getSeconds(), 1.0) != 0)
+      {
+        snprintf(buffer, 9, "%.05f", time.getSeconds());
+
+        std::string decimal = buffer;
+        // find trailing zeros and erase them
+        decimal = decimal.erase(decimal.find_last_not_of('0') + 1, std::string::npos).substr(decimal.find("."));
+        xsd_str += decimal;
+      }
+
+      return xsd_str + std::string{time.getTimezone()};
+    }
+
+    static const inline simple::Time fromXSDRepresentation(basyx::object value)
+    {
+      std::string xsd_str = value.GetStringContent();
+
+      std::smatch match;
+      std::regex regex{"(\\d\\d):(\\d\\d):(\\d\\d(\\.\\d+)?)([Z|\\+|\\-].*)"};
+      std::regex_search(xsd_str, match, regex);
+
+      float second = 0;
+      uint8_t hour = std::stoi(match.str(1)); // first (\\d\\d)
+      uint8_t minute = std::stoi(match.str(2)); // second (\\d\\d)
+      second = std::stof(match.str(3)); // (\\d\\d(\\.\\d+)?) Two digits plus optional decimal point and arbitrary number of digits
+      std::string timezone = match.str(5); // ([Z|\+|\-]) "Z" or + or - and arbitrary characters
+
+      return simple::Time{hour, minute, second, timezone};
+    }
+  };
+
+  template<>
+  struct xsd_type<simple::GYearMonth>
+  {
+    static const std::string getDataTypeDef()
+    {
+      return "gYearMonth";
+    }
+
+    static const inline std::string getXSDRepresentation(const simple::GYearMonth & date)
+    {
+      char buffer[15];
+      if (date.getYear() < 0)
+        snprintf(buffer, 15, "%05d-%02d", date.getYear(), date.getMonth());
+      else
+        snprintf(buffer, 15, "%04d-%02d", date.getYear(), date.getMonth());
+
+      return buffer + std::string{date.getTimezone()};
+    }
+
+    static const inline simple::GYearMonth fromXSDRepresentation(basyx::object value)
+    {
+      std::string xsd_str = value.GetStringContent();
+
+      std::smatch match;
+      std::regex regex{"(-?\\d+)-(\\d\\d)([Z|\\+|\\-].*)"};
+      std::regex_search(xsd_str, match, regex);
+
+      int year = std::stoi(match.str(1)); // first (\\d+)
+      uint8_t month = std::stoi(match.str(2)); // second (\\d\\d)
+      std::string timezone = match.str(3);
+
+      return simple::GYearMonth{year, month, timezone};
+    }
+  };
+
+  template<>
+  struct xsd_type<simple::GYear>
+  {
+    static const std::string getDataTypeDef()
+    {
+      return "gYear";
+    }
+
+    static const inline std::string getXSDRepresentation(const simple::GYear & year)
+    {
+      char buffer[15];
+      if (year.getYear() < 0)
+        snprintf(buffer, 15, "%05d", year.getYear());
+      else
+        snprintf(buffer, 15, "%04d", year.getYear());
+
+      return buffer + std::string{year.getTimezone()};
+    }
+
+    static const inline simple::GYear fromXSDRepresentation(basyx::object value)
+    {
+      std::string xsd_str = value.GetStringContent();
+
+      std::smatch match;
+      std::regex regex{"(-?\\d+)([Z|\\+|\\-].*)"};
+      std::regex_search(xsd_str, match, regex);
+
+      int year = std::stoi(match.str(1)); // first (\\d+)
+      std::string timezone = match.str(2);
+
+      return simple::GYear{year, timezone};
+    }
+  };
+
+  template<>
+  struct xsd_type<simple::GMonthDay>
+  {
+    static const std::string getDataTypeDef()
+    {
+      return "gMonthDay";
+    }
+
+    static const inline std::string getXSDRepresentation(const simple::GMonthDay & monthDay)
+    {
+      char buffer[10];
+      snprintf(buffer, 8, "--%02d-%02d", monthDay.getMonth(), monthDay.getDay());
+
+      return buffer + std::string{monthDay.getTimezone()};
+    }
+
+    static const inline simple::GMonthDay fromXSDRepresentation(basyx::object value)
+    {
+      std::string xsd_str = value.GetStringContent();
+
+      std::smatch match;
+      std::regex regex{"\\-\\-(\\d\\d)\\-(\\d\\d)([Z|\\+|\\-].*)"};
+      std::regex_search(xsd_str, match, regex);
+
+      uint8_t month = std::stoi(match.str(1)); // first (\\d\\d)
+      uint8_t day = std::stoi(match.str(2)); // second (\\d\\d)
+      std::string timezone = match.str(3);
+
+      return simple::GMonthDay{month, day, timezone};
+    }
+  };
+
+  template<>
+  struct xsd_type<simple::GDay>
+  {
+    static const std::string getDataTypeDef()
+    {
+      return "gDay";
+    }
+
+    static const inline std::string getXSDRepresentation(const simple::GDay & day)
+    {
+      char buffer[7];
+      snprintf(buffer, 7, "---%02d", day.getDay());
+
+      return buffer + std::string{day.getTimezone()};
+    }
+
+    static const inline simple::GDay fromXSDRepresentation(basyx::object value)
+    {
+      std::string xsd_str = value.GetStringContent();
+
+      std::smatch match;
+      std::regex regex{"\\-\\-\\-(\\d\\d)([Z|\\+|\\-].*)"};
+      std::regex_search(xsd_str, match, regex);
+
+      uint8_t day = std::stoi(match.str(1)); // first (\\d\\d)
+      std::string timezone = match.str(2);
+
+      return simple::GDay{day, timezone};
+    }
+  };
+
+  template<>
+  struct xsd_type<simple::GMonth>
+  {
+    static const std::string getDataTypeDef()
+    {
+      return "gMonth";
+    }
+
+    static const inline std::string getXSDRepresentation(const simple::GMonth & month)
+    {
+      char buffer[6];
+      snprintf(buffer, 6, "--%02d", month.getMonth());
+
+      return buffer + std::string{month.getTimezone()};
+    }
+
+    static const inline simple::GMonth fromXSDRepresentation(basyx::object value)
+    {
+      std::string xsd_str = value.GetStringContent();
+
+      std::smatch match;
+      std::regex regex{"\\-\\-(\\d\\d)([Z|\\+|\\-].*)"};
+      std::regex_search(xsd_str, match, regex);
+
+      uint8_t month = std::stoi(match.str(1)); // first (\\d\\d)
+      std::string timezone = match.str(2);
+
+      return simple::GMonth{month, timezone};
+    }
+  };
+
+}
+}
+
+
+#endif //BASYX_C_SDK_XSDANYSIMPLETYPE_H
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/ConnectedElement.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/ConnectedElement.h
deleted file mode 100644
index 19a6bc1..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/ConnectedElement.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * ConnectedElement.h
- *
- *      Author: wendel
- */
-
-#ifndef BASYX_METAMODEL_CONNECTEDELEMENT_H_
-#define BASYX_METAMODEL_CONNECTEDELEMENT_H_
-
-
-#include <BaSyx/vab/core/proxy/VABElementProxy.h>
-#include <BaSyx/submodel/api/IElement.h>
-
-#include <BaSyx/shared/types.h>
-
-#include <string>
-#include <memory>
-
-namespace basyx {
-namespace submodel {
-
-class ConnectedElement : public IElement
-{
-public:
-  ConnectedElement(const std::shared_ptr<vab::core::proxy::IVABElementProxy> & proxy);
-  ConnectedElement(const std::shared_ptr<vab::core::proxy::IVABElementProxy> & proxy, std::shared_ptr<basyx::object::object_map_t> & local_values);
-
-  virtual std::shared_ptr<vab::core::proxy::IVABElementProxy> getProxy() const;
-
-  basyx::object getLocalValue(const std::string & path) const;
-  void setLocalValue(const std::string & path, const basyx::object & value);
-  void setLocalValues(const basyx::object::object_map_t & map);
-  void updateLocalValue(const std::string & path, const basyx::object value);
-
-  // Inherited via IElement
-  virtual void setId(const std::string & id) override;
-  virtual std::string getId() const override;
-
-
-private:
-  std::shared_ptr<vab::core::proxy::IVABElementProxy> proxy;
-  std::shared_ptr<basyx::object::object_map_t> local_map;
-
-protected:
-  std::string getProxyValue(const std::string & path) const;
-  std::shared_ptr<basyx::object::object_map_t> getProxyMap(const std::string & path) const;
-  void setProxyValue(const std::string & path, const basyx::object value) const;
-
-};
-
-}
-}
-
-#endif // !BASYX_METAMODEL_CONNECTEDELEMENT_H_
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/ConnectedSubmodel.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/ConnectedSubmodel.h
deleted file mode 100644
index 6aef83a..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/ConnectedSubmodel.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * ConnectedSubmodel.h
- *
- *      Author: wendel
- */
-
-#ifndef CONNECTEDSUBMODEL_H_
-#define CONNECTEDSUBMODEL_H_
-
-#include <BaSyx/submodel/api/ISubModel.h>
-
-#include <BaSyx/submodel/map/IVABElementContainer.h>
-//#include <BaSyx/submodel/map/qualifier/Kind.h>
-#include <BaSyx/submodel/connected/ConnectedElement.h>
-#include <BaSyx/submodel/api/reference/IReference.h>
-
-namespace basyx {
-namespace submodel {
-
-class ConnectedSubmodel : 
-	public ISubModel, 
-	public ConnectedElement
-{
-public:
-  ~ConnectedSubmodel() = default;
-
-  // Inherited via ISubModel
-  virtual std::shared_ptr<IReference> getSemanticId() const override;
-  virtual std::shared_ptr<IAdministrativeInformation> getAdministration() const override;
-  virtual std::shared_ptr<IIdentifier> getIdentification() const override;
-  virtual basyx::specificCollection_t<IReference> getDataSpecificationReferences() const override;
-  virtual Kind getHasKindReference() const override;
-  virtual void setDataElements(const basyx::specificMap_t<IProperty> & properties);
-  virtual void setOperations(const basyx::specificMap_t<IOperation> & operations);
-  virtual std::string getIdShort() const override;
-  virtual std::string getCategory() const override;
-  virtual Description getDescription() const override;
-  virtual std::shared_ptr<IReference> getParent() const override;
-  virtual void addSubModelElement(const std::shared_ptr<ISubmodelElement> & element) override;
-  virtual basyx::specificMap_t<IDataElement> getDataElements() const override;
-  virtual basyx::specificMap_t<IOperation> getOperations() const override;
-
-private:
-  basyx::object::object_map_t local_map;
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/ConnectedVABModelMap.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/ConnectedVABModelMap.h
deleted file mode 100644
index 793090f..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/ConnectedVABModelMap.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * ConnectedVABModelMap.h
- *
- *      Author: wendel
- */
-
-#ifndef CONNECTEDVABMODELMAP_H_
-#define CONNECTEDVABMODELMAP_H_
-
-#include <BaSyx/submodel/connected/ConnectedElement.h>
-
-namespace basyx {
-namespace submodel {
-namespace backend {
-
-class ConnectedVABModelMap : public ConnectedElement
-{
-public:
-  ConnectedVABModelMap(std::shared_ptr<vab::core::proxy::IVABElementProxy> proxy);
-  ~ConnectedVABModelMap() = default;
-};
-
-}
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/ConnectedDataElement.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/ConnectedDataElement.h
deleted file mode 100644
index 78f11c3..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/ConnectedDataElement.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * ConnectedDataElement.h
- *
- *      Author: wendel
- */
-
-
-#ifndef BASYX_METAMODEL_CONNECTEDDATAELEMENT_H_
-#define BASYX_METAMODEL_CONNECTEDDATAELEMENT_H_
-
-#include <BaSyx/vab/core/proxy/IVABElementProxy.h>
-
-#include <BaSyx/submodel/api/reference/IReference.h>
-#include <BaSyx/submodel/api/qualifier/qualifiable/IConstraint.h>
-#include <BaSyx/submodel/connected/submodelelement/ConnectedSubmodelElement.h>
-#include <BaSyx/submodel/api/submodelelement/IDataElement.h>
-
-namespace basyx {
-namespace submodel {
-
-class ConnectedDataElement : public ConnectedSubmodelElement, public IDataElement
-{
-
-public:
-  ConnectedDataElement(std::shared_ptr<vab::core::proxy::IVABElementProxy> proxy);
-  ~ConnectedDataElement() = default;
-
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/ConnectedRelationshipElement.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/ConnectedRelationshipElement.h
deleted file mode 100644
index ac88a92..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/ConnectedRelationshipElement.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * ConnectedRelationshipElement.h
- *
- *      Author: wendel
- */
-
-#ifndef AAS_BACKEND_SUBMODELELEMENT_CONNECTEDRELATIONSHIPELEMENT_H_
-#define AAS_BACKEND_SUBMODELELEMENT_CONNECTEDRELATIONSHIPELEMENT_H_
-
-#include <BaSyx/shared/types.h>
-
-#include <BaSyx/vab/core/proxy/IVABElementProxy.h>
-
-#include <BaSyx/submodel/api/submodelelement/ISubmodelElement.h>
-#include <BaSyx/submodel/api/submodelelement/IRelationshipElement.h>
-#include <BaSyx/submodel/connected/submodelelement/ConnectedSubmodelElement.h>
-
-#include <string>
-
-namespace basyx {
-namespace submodel {
-
-class ConnectedRelationshipElement : public ConnectedSubmodelElement, public IRelationshipElement
-{
-public:
-  ConnectedRelationshipElement(std::shared_ptr<vab::core::proxy::IVABElementProxy> proxy);
-  ~ConnectedRelationshipElement() = default;
-  
-  // Inherited via IRelationshipElement
-  virtual void setFirst(const IReference & first) override;
-  virtual std::shared_ptr<IReference> getFirst() const override;
-  virtual void setSecond(const IReference & second) override;
-  virtual std::shared_ptr<IReference> getSecond() const override;
-};
-
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/ConnectedSubmodelElement.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/ConnectedSubmodelElement.h
deleted file mode 100644
index 6fa216d..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/ConnectedSubmodelElement.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * ConnectedSubmodelElement.h
- *
- *      Author: wendel
- */
-
-#ifndef AAS_BACKEND_SUBMODELELEMENT_CONNECTED_CONNECTEDSUBMODELELEMENT_H_
-#define AAS_BACKEND_SUBMODELELEMENT_CONNECTED_CONNECTEDSUBMODELELEMENT_H_
-
-#include <BaSyx/submodel/api/submodelelement/ISubmodelElement.h>
-#include <BaSyx/submodel/connected/ConnectedElement.h>
-#include <BaSyx/vab/core/proxy/IVABElementProxy.h>
-
-namespace basyx {
-namespace submodel {
-
-class ConnectedSubmodelElement : public ConnectedElement, public ISubmodelElement
-{
-public:
-  ConnectedSubmodelElement(std::shared_ptr<vab::core::proxy::IVABElementProxy> proxy);
-  ~ConnectedSubmodelElement() = default;
-
-  basyx::specificCollection_t<IReference> getDataSpecificationReferences() const override;
-  std::string getIdShort() const override;
-  std::string getCategory() const override;
-  Description getDescription() const override;
-  std::shared_ptr<IReference> getParent() const override;
-  basyx::specificCollection_t<IConstraint> getQualifier() const override;
-  std::shared_ptr<IReference> getSemanticId() const override;
-  Kind getHasKindReference() const override;
-   
-protected:
-  std::string getIdWithLocalCheck() const;
-  void setIdWithLocalCheck(const std::string & id);
-  basyx::object::object_list_t getProxyCollection(const std::string & path) const;
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/ConnectedSubmodelElementCollection.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/ConnectedSubmodelElementCollection.h
deleted file mode 100644
index b9848ad..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/ConnectedSubmodelElementCollection.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * ConnectedSubmodelElementCollection.h
- *
- *      Author: wendel
- */
-
-#ifndef AAS_BACKEND_SUBMODELELEMENT_CONNECTEDSUBMODELELEMENTCOLLECTION_H_
-#define AAS_BACKEND_SUBMODELELEMENT_CONNECTEDSUBMODELELEMENTCOLLECTION_H_
-
-#include <BaSyx/submodel/connected/submodelelement/ConnectedSubmodelElement.h>
-#include <BaSyx/submodel/api/submodelelement/ISubmodelElementCollection.h>
-
-namespace basyx { 
-namespace submodel {
-
-
-class ConnectedSubmodelElementCollection : public ConnectedSubmodelElement, ISubmodelElementCollection
-{
-public:
-  ConnectedSubmodelElementCollection(std::shared_ptr<vab::core::proxy::IVABElementProxy> proxy);
-  ~ConnectedSubmodelElementCollection() = default;
-
-  // Inherited via ISubmodelElementCollection
-  virtual void setValue(const basyx::specificCollection_t<ISubmodelElement> & value) ;
-  virtual basyx::specificCollection_t<ISubmodelElement> getValue() const override;
-  virtual void setOrdered(const bool & value) ;
-  virtual bool isOrdered() const override;
-  virtual void setAllowDuplicates(const bool & value) ;
-  virtual bool isAllowDuplicates() const override;
-  virtual void setElements(const basyx::specificMap_t<ISubmodelElement> & elements) ;
-  virtual basyx::specificMap_t<ISubmodelElement> getElements() const override;
-};
-
-}
-} 
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/operation/ConnectedOperation.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/operation/ConnectedOperation.h
deleted file mode 100644
index 682019b..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/operation/ConnectedOperation.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * ConnectedOperation.h
- *
- *      Author: wendel
- */
-
-#ifndef AAS_BACKEND_SUBMODELELEMENT_OPERATION_CONNECTEDOPERATION_H_
-#define AAS_BACKEND_SUBMODELELEMENT_OPERATION_CONNECTEDOPERATION_H_
-
-#include <BaSyx/submodel/api/submodelelement/operation/IOperation.h>
-#include <BaSyx/vab/core/proxy/IVABElementProxy.h>
-#include <BaSyx/submodel/connected/submodelelement/ConnectedSubmodelElement.h>
-
-namespace basyx { 
-namespace submodel {
-
-class ConnectedOperation : public ConnectedSubmodelElement, public IOperation
-{
-public:
-  ConnectedOperation(std::shared_ptr<vab::core::proxy::IVABElementProxy> proxy);
-	~ConnectedOperation() = default;
-
-  // Inherited via IOperation
-  virtual void setId(const std::string & id) override;
-  virtual std::string getId() const override;
-
-  virtual basyx::specificCollection_t<IOperationVariable> getParameterTypes() const override;
-  virtual std::shared_ptr<IOperationVariable> getReturnType() const override;
-  virtual basyx::object invoke(basyx::object & parameters) const override;
-  virtual basyx::object getInvocable() const override;
-};
- 
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/property/ConnectedCollectionProperty.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/property/ConnectedCollectionProperty.h
deleted file mode 100644
index 17f8a4e..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/property/ConnectedCollectionProperty.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * ConnectedCollectionProperty.h
- *
- *      Author: wendel
- */
-
-#ifndef AAS_BACKEND_SUBMODELELEMENT_PROPERTY_CONNECTEDCOLLECTIONPROPERTY_H_
-#define AAS_BACKEND_SUBMODELELEMENT_PROPERTY_CONNECTEDCOLLECTIONPROPERTY_H_
-
-#include <BaSyx/submodel/api/submodelelement/property/ICollectionProperty.h>
-#include <BaSyx/submodel/connected/submodelelement/property/ConnectedProperty.h>
-
-namespace basyx { 
-namespace submodel {
-
-class ConnectedCollectionProperty : public ConnectedProperty, submodelelement::property::ICollectionProperty
-{
-public:
-  ConnectedCollectionProperty(std::shared_ptr<vab::core::proxy::IVABElementProxy> proxy);
-	~ConnectedCollectionProperty() = default;
-
-  virtual void set(const basyx::object::object_list_t & collection) const override;
-  virtual void add(const basyx::object & newValue) override;
-  virtual void remove(basyx::object & objectRef) override;
-  virtual basyx::object::object_list_t getElements() const override;
-  virtual int getElementCount() const override;
-
-};
- 
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/property/ConnectedContainerProperty.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/property/ConnectedContainerProperty.h
deleted file mode 100644
index d339c0f..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/property/ConnectedContainerProperty.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * ConnectedContainerProperty.h
- *
- *      Author: wendel
- */
-
-#ifndef AAS_BACKEND_SUBMODELELEMENT_PROPERTY_CONNECTEDCONTAINERPROPERTY_H_
-#define AAS_BACKEND_SUBMODELELEMENT_PROPERTY_CONNECTEDCONTAINERPROPERTY_H_
-
-#include <BaSyx/submodel/connected/submodelelement/property/ConnectedCollectionProperty.h>
-
-namespace basyx { 
-namespace submodel {
-namespace backend {
-namespace connected { 
-
-using ConnectedContainerProperty = ConnectedCollectionProperty;
- 
-}
-}
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/property/ConnectedMapProperty.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/property/ConnectedMapProperty.h
deleted file mode 100644
index d6ecb67..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/property/ConnectedMapProperty.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * ConnectedMapProperty.h
- *
- *      Author: wendel
- */
-
-#ifndef AAS_BACKEND_SUBMODELELEMENT_PROPERTY_CONNECTEDMAPPROPERTY_H_
-#define AAS_BACKEND_SUBMODELELEMENT_PROPERTY_CONNECTEDMAPPROPERTY_H_
-
-#include <BaSyx/submodel/connected/submodelelement/property/ConnectedProperty.h>
-#include <BaSyx/submodel/api/submodelelement/property/IMapProperty.h>
-
-namespace basyx { 
-namespace submodel {
-
-class ConnectedMapProperty : public submodelelement::property::IMapProperty, public ConnectedProperty
-{
-public:
-  ConnectedMapProperty(std::shared_ptr<vab::core::proxy::IVABElementProxy> proxy);
-	~ConnectedMapProperty() = default;
-
-  // Inherited via IMapProperty
-  virtual basyx::object getValue(const std::string & key) const override;
-  virtual void put(const std::string & key, const basyx::object & value) const override;
-  virtual void set(const basyx::object::object_map_t & map) const override;
-  virtual basyx::object::object_list_t getKeys() const override;
-  virtual int getEntryCount() const override;
-  virtual void remove(const std::string & key) const override;
-
-private:
-  basyx::object::object_map_t getMap() const;
-};
- 
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/property/ConnectedProperty.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/property/ConnectedProperty.h
deleted file mode 100644
index 88b7732..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/property/ConnectedProperty.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * ConnectedProperty.h
- *
- *      Author: wendel
- */
-
-#ifndef AAS_BACKEND_CONNECTEDPROPERTY_H_
-#define AAS_BACKEND_CONNECTEDPROPERTY_H_
-
-#include <BaSyx/submodel/api/submodelelement/property/IProperty.h>
-#include <BaSyx/submodel/connected/submodelelement/ConnectedDataElement.h>
-#include <BaSyx/shared/types.h>
-#include <BaSyx/shared/object.h>
-
-namespace basyx {
-namespace submodel {
-
-class ConnectedProperty : public ConnectedDataElement, public IProperty
-{
-
-public:
-  ConnectedProperty(PropertyType type, std::shared_ptr<vab::core::proxy::IVABElementProxy> proxy);
-
-  // Inherited via IProperty
-  virtual PropertyType getPropertyType() const override;
-
-  //Inherited via IProperty : IElement
-  virtual void setId(const std::string & id) override;
-  virtual std::string getId() const override;
-
-protected:
-  basyx::object retrieveObject() const;
-
-private:
-  PropertyType type;
-
-  // Inherited via IProperty
-  virtual void setValueId(const std::string & valueId) override;
-  virtual std::string getValueId() const override;
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/property/ConnectedPropertyFactory.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/property/ConnectedPropertyFactory.h
deleted file mode 100644
index 13fd67d..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/property/ConnectedPropertyFactory.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * ConnectedPropertyFactory.h
- *
- *      Author: wendel
- */
-
-#ifndef AAS_BACKEND_SUBMODELELEMENT_PROPERTY_CONNECTEDPROPERTYFACTORY_H_
-#define AAS_BACKEND_SUBMODELELEMENT_PROPERTY_CONNECTEDPROPERTYFACTORY_H_
-
-#include <BaSyx/submodel/api/submodelelement/property/IProperty.h>
-#include <BaSyx/vab/core/proxy/IVABElementProxy.h>
-#include <BaSyx/submodel/api/ISubModel.h>
-#include <BaSyx/submodel/connected/submodelelement/property/ConnectedContainerProperty.h>
-#include <BaSyx/submodel/connected/submodelelement/property/ConnectedMapProperty.h>
-#include <BaSyx/submodel/connected/submodelelement/property/ConnectedSingleProperty.h>
-#include <BaSyx/submodel/api/submodelelement/property/ISingleProperty.h>
-#include <BaSyx/submodel/map/submodelelement/property/valuetypedef/PropertyValueTypeDef.h>
-
-
-namespace basyx {
-namespace submodel {
-namespace backend {
-namespace connected {
-namespace support {
-
-using namespace submodelelement::property;
-
-namespace ConnectedPropertyFactory {
-// Forward declaration
-static std::shared_ptr<ConnectedProperty> createSuitableProperty(std::shared_ptr<vab::core::proxy::IVABElementProxy> proxy, basyx::object::object_map_t & originalPropertyMap, basyx::object::object_map_t & valueTypeMap);
-static std::shared_ptr<ConnectedProperty> createSingleProperty(std::shared_ptr<vab::core::proxy::IVABElementProxy> proxy, basyx::object::object_map_t & originalPropertyMap);
-static std::shared_ptr<ConnectedProperty> createProperty(std::shared_ptr<vab::core::proxy::IVABElementProxy> proxy)
-{
-  auto property = proxy->readElementValue("").Get<basyx::object::object_map_t>();
-
-
-  // todo
-  //if ( property.find(api::ISubModel::SubmodelPaths::PROPERTIES) != property.end() )
-  //{
-  //  return std::make_shared<ConnectedContainerProperty>(proxy);
-  //}
-
-  auto valueTypePtr = property.find(IProperty::Path::ValueType);
-  // Check if valueType is set
-  if ( valueTypePtr != property.end() )
-  {
-    auto valueType = valueTypePtr->second.Get<basyx::object::object_map_t>();
-    return createSuitableProperty(proxy, property, valueType);
-  }
-
-  // Property with no value type set
-  if ( property.find(IProperty::Path::Value) != property.end() and property.find(IReferable::Path::IdShort) != property.end() )
-  {
-    return createSingleProperty(proxy, property);
-  }
-
-  // If nothing suits return null
-  return nullptr;
-}
-
-static std::shared_ptr<ConnectedProperty> createSuitableProperty(std::shared_ptr<vab::core::proxy::IVABElementProxy> proxy, basyx::object::object_map_t & originalPropertyMap, basyx::object::object_map_t & valueTypeMap)
-{
-  auto valueType_typeObject = valueTypeMap.at(impl::metamodel::PropertyValueTypeIdentifier::TYPE_OBJECT).Get<basyx::object::object_map_t>();
-  auto propertyValueTypeName = valueType_typeObject.at(impl::metamodel::PropertyValueTypeIdentifier::TYPE_NAME).GetStringContent();
-
-  // if map -> create map todo
-  //if ( propertyValueTypeName.compare(impl::metamodel::PropertyValueTypeDef::Map) == 0 )
-  //{
-  //  return std::make_shared<ConnectedMapProperty>(proxy);
-  //}
-
-  // if collection -> create collection todo
-  //if ( propertyValueTypeName.compare(impl::metamodel::PropertyValueTypeDef::Collection) == 0 )
-  //{
-  //  return std::make_shared<ConnectedCollectionProperty>(proxy);
-  //}
-
-  // if no map and no collection -> must be single property
-  //else
-  //{
-  //  return createSingleProperty(proxy, originalPropertyMap);
-  //}
-  return nullptr;
-}
-
-static std::shared_ptr<ConnectedProperty> createSingleProperty(std::shared_ptr<vab::core::proxy::IVABElementProxy> proxy, basyx::object::object_map_t & originalPropertyMap)
-{
-  ConnectedSingleProperty singleProperty(proxy);
-  for ( auto & element : originalPropertyMap )
-  {
-    singleProperty.setLocalValue(element.first, element.second);
-  }
-  return std::make_shared<ConnectedCollectionProperty>(proxy);
-}
-}
-
-}
-}
-}
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/property/ConnectedReferenceElement.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/property/ConnectedReferenceElement.h
deleted file mode 100644
index 4d371a7..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/property/ConnectedReferenceElement.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * ConnectedReferenceElement.h
- *
- *      Author: wendel
- */
-
-#ifndef AAS_BACKEND_SUBMODELELEMENT_PROPERTY_CONNECTEDREFERENCEELEMENT_H_
-#define AAS_BACKEND_SUBMODELELEMENT_PROPERTY_CONNECTEDREFERENCEELEMENT_H_
-
-#include <BaSyx/submodel/connected/submodelelement/ConnectedDataElement.h>
-#include <BaSyx/submodel/api/submodelelement/IReferenceElement.h>
-
-namespace basyx {
-namespace submodel {
-
-class ConnectedReferenceElement : public ConnectedDataElement, public IReferenceElement
-{
-public:
-  ConnectedReferenceElement(std::shared_ptr<vab::core::proxy::IVABElementProxy> proxy);
-  ~ConnectedReferenceElement() = default;
-
-  virtual void setValue(const IReference & ref);
-  virtual std::shared_ptr<IReference> getValue() const override;
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/property/ConnectedSingleProperty.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/property/ConnectedSingleProperty.h
deleted file mode 100644
index e1a0ba7..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/property/ConnectedSingleProperty.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * ConnectedSingleProperty.h
- *
- *      Author: wendel
- */
-
-#ifndef AAS_BACKEND_SUBMODELELEMENT_PROPERTY_CONNECTEDSINGLEPROPERTY_H_
-#define AAS_BACKEND_SUBMODELELEMENT_PROPERTY_CONNECTEDSINGLEPROPERTY_H_
-
-#include <BaSyx/submodel/connected/submodelelement/property/ConnectedProperty.h>
-#include <BaSyx/submodel/api/submodelelement/property/ISingleProperty.h>
-
-namespace basyx {
-namespace submodel {
-
-class ConnectedSingleProperty : public ConnectedProperty, public ISingleProperty
-{
-public:
-  ConnectedSingleProperty(std::shared_ptr<vab::core::proxy::IVABElementProxy> proxy);
-  ~ConnectedSingleProperty() = default;
-
-  virtual basyx::object get() const override;
-  virtual void set(const basyx::object & value) override;
-  virtual std::string getValueType() const override;
-
-
-  // Inherited via ConnectedProperty
-  virtual void setValueId(const std::string & valueId) override;
-  virtual std::string getValueId() const override;
-  virtual PropertyType getPropertyType() const override;
-
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/property/blob/ConnectedBlob.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/property/blob/ConnectedBlob.h
deleted file mode 100644
index 8659ef7..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/property/blob/ConnectedBlob.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * ConnectedBlob.h
- *
- *      Author: wendel
- */
-
-#ifndef AAS_BACKEND_SUBMODELELEMENT_PROPERTY_CONNECTEDBLOB_H_
-#define AAS_BACKEND_SUBMODELELEMENT_PROPERTY_CONNECTEDBLOB_H_
-
-#include <BaSyx/submodel/api/submodelelement/property/blob/IBlob.h>
-#include <BaSyx/submodel/connected/submodelelement/ConnectedDataElement.h>
-//#include <BaSyx/aas/BlobType.h>
-//#include <BaSyx/aas/MimeType.h>
-
-namespace basyx {
-namespace submodel {
-
-class ConnectedBlob : public IBlob, ConnectedDataElement
-{
-public:
-  ConnectedBlob(std::shared_ptr<vab::core::proxy::IVABElementProxy> proxy);
-  ~ConnectedBlob() = default;
-
-  // Inherited via IBlob
-  virtual void setValue(const std::string & value);
-
-  virtual const std::string & getValue() const override;
-
-  virtual void setMimeType(const std::string & mimeType);
-
-  virtual const std::string & getMimeType() const override;
-
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/property/file/ConnectedFile.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/property/file/ConnectedFile.h
deleted file mode 100644
index 5ac4a88..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/connected/submodelelement/property/file/ConnectedFile.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * ConnectedFile.h
- *
- *      Author: wendel
- */
-
-#ifndef AAS_BACKEND_SUBMODELELEMENT_PROPERTY_CONNECTEDFILE_H_
-#define AAS_BACKEND_SUBMODELELEMENT_PROPERTY_CONNECTEDFILE_H_
-
-#include <BaSyx/submodel/api/submodelelement/property/file/IFile.h>
-#include <BaSyx/submodel/connected/submodelelement/ConnectedDataElement.h>
-
-namespace basyx { 
-namespace submodel {
-
-class ConnectedFile : public IFile, ConnectedDataElement
-{
-public:
-  ConnectedFile(std::shared_ptr<vab::core::proxy::IVABElementProxy> proxy);
-	~ConnectedFile() = default;
-
-  virtual void setValue(const std::string & value);
-  virtual const std::string & getValue() const override;
-
-  virtual void setMimeType(const std::string & mimeType);
-  virtual const std::string & getMimeType() const override;
-
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/AssetKind.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/AssetKind.h
index 4576d7f..277bd0f 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/AssetKind.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/AssetKind.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_SUBMODEL_ENUM_AssetKind_H
-#define BASYX_SUBMODEL_ENUM_AssetKind_H
+#ifndef BASYX_SUBMODEL_ENUMERATIONS_ASSETKIND_H
+#define BASYX_SUBMODEL_ENUMERATIONS_ASSETKIND_H
 
 #include <string>
 
@@ -23,4 +23,4 @@
 }
 }
 
-#endif
+#endif /* BASYX_SUBMODEL_ENUMERATIONS_ASSETKIND_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/Conversions.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/Conversions.h
new file mode 100644
index 0000000..944934b
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/Conversions.h
@@ -0,0 +1,79 @@
+#ifndef BASYX_SUBMODEL_ENUMERATIONS_CONVERSIONS_H
+#define BASYX_SUBMODEL_ENUMERATIONS_CONVERSIONS_H
+
+#include <BaSyx/submodel/enumerations/KeyElements.h>
+#include <BaSyx/submodel/enumerations/ModelTypes.h>
+
+namespace basyx {
+namespace submodel {
+namespace enums {
+
+inline KeyElements convert_modeltype_to_keyelement(const ModelTypes modelType)
+{
+    switch (modelType) {
+    case ModelTypes::Asset:
+        return KeyElements::Asset;
+    case ModelTypes::AssetAdministrationShell:
+        return KeyElements::AssetAdministrationShell;
+    case ModelTypes::ConceptDescription:
+        return KeyElements::ConceptDescription;
+    case ModelTypes::Submodel:
+        return KeyElements::Submodel;
+    case ModelTypes::AccessPermissionRule:
+        return KeyElements::AccessPermissionRule;
+    case ModelTypes::AnnotatedRelationshipElement:
+        return KeyElements::AnnotatedRelationshipElement;
+    case ModelTypes::BasicEvent:
+        return KeyElements::BasicEvent;
+    case ModelTypes::Blob:
+        return KeyElements::Blob;
+    case ModelTypes::Capability:
+        return KeyElements::Capability;
+    case ModelTypes::ConceptDictionary:
+        return KeyElements::ConceptDictionary;
+    case ModelTypes::DataElement:
+        return KeyElements::DataElement;
+    case ModelTypes::File:
+        return KeyElements::File;
+    case ModelTypes::Entity:
+        return KeyElements::Entity;
+    case ModelTypes::Event:
+        return KeyElements::Event;
+    case ModelTypes::MultiLanguageProperty:
+        return KeyElements::MultiLanguageProperty;
+    case ModelTypes::Operation:
+        return KeyElements::Operation;
+    case ModelTypes::OperationVariable:
+        return KeyElements::OperationVariable;
+    case ModelTypes::Property:
+        return KeyElements::Property;
+    case ModelTypes::Range:
+        return KeyElements::Range;
+    case ModelTypes::ReferenceElement:
+        return KeyElements::ReferenceElement;
+    case ModelTypes::RelationshipElement:
+        return KeyElements::RelationshipElement;
+    case ModelTypes::SubmodelElement:
+        return KeyElements::SubmodelElement;
+    case ModelTypes::SubmodelElementCollection:
+        return KeyElements::SubmodelElementCollection;
+    case ModelTypes::View:
+        return KeyElements::View;
+    case ModelTypes::GlobalReference:
+        return KeyElements::GlobalReference;
+    case ModelTypes::FragmentReference:
+        return KeyElements::FragmentReference;
+    case ModelTypes::Constraint:
+        return KeyElements::Unknown;
+    case ModelTypes::Formula:
+        return KeyElements::Unknown;
+    case ModelTypes::Qualifier:
+        return KeyElements::Unknown;
+    };
+};
+
+}
+}
+}
+
+#endif /* BASYX_SUBMODEL_ENUMERATIONS_CONVERSIONS_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/DataTypeIEC61360.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/DataTypeIEC61360.h
index 634c85b..a06b777 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/DataTypeIEC61360.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/DataTypeIEC61360.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_SUBMODEL_ENUM_DataTypeIEC61360_H
-#define BASYX_SUBMODEL_ENUM_DataTypeIEC61360_H
+#ifndef BASYX_SUBMODEL_ENUMERATIONS_DATATYPEIEC61360_H
+#define BASYX_SUBMODEL_ENUMERATIONS_DATATYPEIEC61360_H
 
 #include <string>
 
@@ -33,4 +33,4 @@
 }
 }
 
-#endif
+#endif /* BASYX_SUBMODEL_ENUMERATIONS_DATATYPEIEC61360_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/EntityType.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/EntityType.h
index c5fd70e..7459c3b 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/EntityType.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/EntityType.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_SUBMODEL_ENUM_EntityType_H
-#define BASYX_SUBMODEL_ENUM_EntityType_H
+#ifndef BASYX_SUBMODEL_ENUMERATIONS_ENTITYTYPE_H
+#define BASYX_SUBMODEL_ENUMERATIONS_ENTITYTYPE_H
 
 #include <string>
 
@@ -22,4 +22,4 @@
 }
 }
 
-#endif
+#endif /* BASYX_SUBMODEL_ENUMERATIONS_ENTITYTYPE_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/IdentifiableElements.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/IdentifiableElements.h
index bc824f1..1ecc764 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/IdentifiableElements.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/IdentifiableElements.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_SUBMODEL_ENUM_IdentifiableElements_H
-#define BASYX_SUBMODEL_ENUM_IdentifiableElements_H
+#ifndef BASYX_SUBMODEL_ENUMERATIONS_IDENTIFIABLEELEMENTS_H
+#define BASYX_SUBMODEL_ENUMERATIONS_IDENTIFIABLEELEMENTS_H
 
 #include <string>
 
@@ -7,24 +7,10 @@
 namespace submodel {
 
 enum class IdentifiableElements {
-    AccessPermissionRule,
-    AnnotatedRelationshipElemenBasicEvent,
-    Blob,
-    Capability,
-    ConceptDictionary,
-    DataElement,
-    Entity,
-    Event,
-    File,
-    MultiLanguageProperty,
-    Operation,
-    Property,
-    Range,
-    ReferenceElement,
-    RelationshipElement,
-    SubmodelElement,
-    SubmodelElementCollection,
-    View,
+    Asset,
+    AssetAdministrationShell,
+    ConceptDescription,
+    Submodel,
 };
 
 class IdentifiableElements_
@@ -38,4 +24,4 @@
 }
 }
 
-#endif
+#endif /* BASYX_SUBMODEL_ENUMERATIONS_IDENTIFIABLEELEMENTS_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/IdentifierType.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/IdentifierType.h
index 3357dd5..b021cb9 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/IdentifierType.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/IdentifierType.h
@@ -1,27 +1,32 @@
-#ifndef BASYX_SUBMODEL_ENUM_IdentifierType_H
-#define BASYX_SUBMODEL_ENUM_IdentifierType_H
+#ifndef BASYX_SUBMODEL_ENUMERATIONS_IDENTIFIERTYPE_H
+#define BASYX_SUBMODEL_ENUMERATIONS_IDENTIFIERTYPE_H
+
+#include <BaSyx/submodel/enumerations/KeyType.h>
 
 #include <string>
 
 namespace basyx {
 namespace submodel {
 
-enum class IdentifierType {
-    Custom,
-    IRDI,
-    URI,
-    Unknown,
-};
+using IdentifierType = KeyType;
+using IdentifierType_ = KeyType_;
 
-class IdentifierType_
-{
-public:
-    static IdentifierType from_string(const std::string & name);
-    static const char * to_string(IdentifierType value);
-};
+//enum class IdentifierType {
+//    Custom,
+//    IRDI,
+//    URI,
+//    Unknown,
+//};
+//
+//class IdentifierType_
+//{
+//public:
+//    static IdentifierType from_string(const std::string & name);
+//    static const char * to_string(IdentifierType value);
+//};
 
 
 }
 }
 
-#endif
+#endif /* BASYX_SUBMODEL_ENUMERATIONS_IDENTIFIERTYPE_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/KeyElements.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/KeyElements.h
index e6248d7..ef616a5 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/KeyElements.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/KeyElements.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_SUBMODEL_ENUM_KeyElements_H
-#define BASYX_SUBMODEL_ENUM_KeyElements_H
+#ifndef BASYX_SUBMODEL_ENUMERATIONS_KEYELEMENTS_H
+#define BASYX_SUBMODEL_ENUMERATIONS_KEYELEMENTS_H
 
 #include <string>
 
@@ -21,6 +21,7 @@
     File,
     MultiLanguageProperty,
     Operation,
+    OperationVariable,
     Property,
     Range,
     ReferenceElement,
@@ -46,4 +47,4 @@
 }
 }
 
-#endif
+#endif /* BASYX_SUBMODEL_ENUMERATIONS_KEYELEMENTS_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/KeyType.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/KeyType.h
index 2111f59..9918683 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/KeyType.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/KeyType.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_SUBMODEL_ENUM_KeyType_H
-#define BASYX_SUBMODEL_ENUM_KeyType_H
+#ifndef BASYX_SUBMODEL_ENUMERATIONS_KEYTYPE_H
+#define BASYX_SUBMODEL_ENUMERATIONS_KEYTYPE_H
 
 #include <string>
 
@@ -26,4 +26,4 @@
 }
 }
 
-#endif
+#endif /* BASYX_SUBMODEL_ENUMERATIONS_KEYTYPE_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/LevelType.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/LevelType.h
index b2231e6..502a9ae 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/LevelType.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/LevelType.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_SUBMODEL_ENUM_LevelType_H
-#define BASYX_SUBMODEL_ENUM_LevelType_H
+#ifndef BASYX_SUBMODEL_ENUMERATIONS_LEVELTYPE_H
+#define BASYX_SUBMODEL_ENUMERATIONS_LEVELTYPE_H
 
 #include <string>
 
@@ -25,4 +25,4 @@
 }
 }
 
-#endif
+#endif /* BASYX_SUBMODEL_ENUMERATIONS_LEVELTYPE_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/LocalKeyType.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/LocalKeyType.h
index 1ea373a..929c7f5 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/LocalKeyType.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/LocalKeyType.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_SUBMODEL_ENUM_LocalKeyType_H
-#define BASYX_SUBMODEL_ENUM_LocalKeyType_H
+#ifndef BASYX_SUBMODEL_ENUMERATIONS_LOCALKEYTYPE_H
+#define BASYX_SUBMODEL_ENUMERATIONS_LOCALKEYTYPE_H
 
 #include <string>
 
@@ -22,4 +22,4 @@
 }
 }
 
-#endif
+#endif /* BASYX_SUBMODEL_ENUMERATIONS_LOCALKEYTYPE_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/ModelTypes.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/ModelTypes.h
index 808a567..4d831a4 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/ModelTypes.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/ModelTypes.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_SUBMODEL_ENUM_ModelTypes_H
-#define BASYX_SUBMODEL_ENUM_ModelTypes_H
+#ifndef BASYX_SUBMODEL_ENUMERATIONS_MODELTYPES_H
+#define BASYX_SUBMODEL_ENUMERATIONS_MODELTYPES_H
 
 #include <string>
 
@@ -49,4 +49,4 @@
 }
 }
 
-#endif
+#endif /* BASYX_SUBMODEL_ENUMERATIONS_MODELTYPES_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/ModelingKind.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/ModelingKind.h
index 4824974..c8f2cdb 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/ModelingKind.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/ModelingKind.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_SUBMODEL_ENUM_ModelingKind_H
-#define BASYX_SUBMODEL_ENUM_ModelingKind_H
+#ifndef BASYX_SUBMODEL_ENUMERATIONS_MODELINGKIND_H
+#define BASYX_SUBMODEL_ENUMERATIONS_MODELINGKIND_H
 
 #include <string>
 
@@ -22,4 +22,4 @@
 }
 }
 
-#endif
+#endif /* BASYX_SUBMODEL_ENUMERATIONS_MODELINGKIND_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/ReferableElements.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/ReferableElements.h
index 3bffca8..5a37c73 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/ReferableElements.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/enumerations/ReferableElements.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_SUBMODEL_ENUM_ReferableElements_H
-#define BASYX_SUBMODEL_ENUM_ReferableElements_H
+#ifndef BASYX_SUBMODEL_ENUMERATIONS_REFERABLEELEMENTS_H
+#define BASYX_SUBMODEL_ENUMERATIONS_REFERABLEELEMENTS_H
 
 #include <string>
 
@@ -38,4 +38,4 @@
 }
 }
 
-#endif
+#endif /* BASYX_SUBMODEL_ENUMERATIONS_REFERABLEELEMENTS_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/BlobType.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/BlobType.h
deleted file mode 100644
index e7fde69..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/BlobType.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * BlobType.h
- *
- *      Author: wendel
- */
-
-#ifndef AAS_BLOBTYPE_H_
-#define AAS_BLOBTYPE_H_
-
-class BlobType
-{
-public:
-	BlobType();
-	~BlobType();
-};
-
-#endif
-
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/IVABElementContainer.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/IVABElementContainer.h
deleted file mode 100644
index dd94ca4..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/IVABElementContainer.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * IVABElementContainer.h
- *
- *      Author: wendel
- */
-
-#ifndef AAS_IMPL_HASHMAP_IVABELEMENTCONTAINER_H_
-#define AAS_IMPL_HASHMAP_IVABELEMENTCONTAINER_H_
-
-#include <BaSyx/shared/types.h>
-#include <BaSyx/submodel/api/submodelelement/IDataElement.h>
-#include <BaSyx/submodel/api/submodelelement/operation/IOperation.h>
-
-namespace basyx {
-namespace submodel {
-namespace map {
-
-class IVABElementContainer
-{
-public:
-	~IVABElementContainer() = default;
-
-	virtual void addSubModelElement(const std::shared_ptr<ISubmodelElement> & element) = 0;
-	virtual basyx::specificMap_t<IDataElement> getDataElements() const = 0;
-	virtual basyx::specificMap_t<IOperation> getOperations() const = 0;
-};
-
-}
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/MimeType.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/MimeType.h
deleted file mode 100644
index fbe836e..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/MimeType.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * MimeType.h
- *
- *      Author: wendel
- */
-
-
-#ifndef AAS_MIMETYPE_H_
-#define AAS_MIMETYPE_H_
-
-class MimeType
-{
-public:
-	MimeType();
-	~MimeType();
-};
-
-#endif
-
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/PathType.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/PathType.h
deleted file mode 100644
index 3c8f60c..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/PathType.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * PathType.h
- *
- *      Author: wendel
- */
-
-#ifndef AAS_PATHTYPE_H_
-#define AAS_PATHTYPE_H_
-
-class PathType
-{
-public:
-	PathType();
-	~PathType();
-};
-
-#endif
-
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/SubModel.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/SubModel.h
deleted file mode 100644
index 3ded138..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/SubModel.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * SubModel.h
- *
- *      Author: kuhn, wendel
- */
-
-#ifndef BASYX_AAS_SUBMODEL_H_
-#define BASYX_AAS_SUBMODEL_H_
-
-
-/* *********************************************************************************
- * Includes
- * *********************************************************************************/
-
-// BaSyx includes
-#include <BaSyx/submodel/api/ISubModel.h>
-#include <BaSyx/submodel/api/qualifier/IHasSemantics.h>
-#include <BaSyx/submodel/api/submodelelement/operation/IOperation.h>
-#include <BaSyx/submodel/map/qualifier/HasSemantics.h>
-#include <BaSyx/submodel/map/qualifier/Identifiable.h>
-#include <BaSyx/submodel/map/qualifier/HasDataSpecification.h>
-#include <BaSyx/submodel/map/qualifier/qualifiable/Qualifiable.h>
-#include <BaSyx/submodel/map/qualifier/HasKind.h>
-#include <BaSyx/submodel/map/modeltype/ModelType.h>
-
-#include <memory>
-
-
-namespace basyx {
-namespace submodel {
-
-/* *********************************************************************************
- * Sub Model base class
- * *********************************************************************************/
-class SubModel : 
-  public virtual ISubModel,
-  public virtual HasDataSpecification,
-  public virtual HasKind,
-  public virtual HasSemantics,
-  public virtual Identifiable,
-  public virtual Qualifiable,
-  public virtual ModelType,
-  public virtual vab::ElementMap
-{
-public:
-	using vab::ElementMap::ElementMap;
-
-	SubModel();
-	SubModel(const IHasSemantics & semantics, const IIdentifiable & identifiable, const IQualifiable & qualifiable, const IHasDataSpecification & specification, const IHasKind & hasKind);
-	SubModel(const ISubModel & submodel);
-
-	// Inherited via ISubModel
-	virtual void setDataElements(const basyx::specificMap_t<IDataElement> & properties);
-	virtual void setOperations(const basyx::specificMap_t<IOperation> & operations);
-
-	virtual void addSubModelElement(const std::shared_ptr<ISubmodelElement>& element);
-	virtual void addOperation(const IOperation & operation);
-	virtual void addDataElement(const IDataElement & dataElement);
-
-	virtual basyx::specificMap_t<ISubmodelElement> getSubmodelElements() const override;
-	virtual basyx::specificMap_t<IDataElement> getDataElements() const override;
-	virtual basyx::specificMap_t<IOperation> getOperations() const override;
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/dataspecification/DataSpecification.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/dataspecification/DataSpecification.h
deleted file mode 100644
index 697cc59..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/dataspecification/DataSpecification.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * DataSpecification.h
- *
- *      Author: wendel
- */
-
-#ifndef BASYX_AAS_DATASPECIFICATION_H_
-#define BASYX_AAS_DATASPECIFICATION_H_
-
-#include <BaSyx/submodel/api/dataspecification/IDataSpecification.h>
-
-#include <BaSyx/submodel/map/qualifier/Identifiable.h>
-#include <BaSyx/submodel/map/qualifier/Referable.h>
-
-namespace basyx {
-namespace submodel {
-
-class DataSpecification
-  : public IDataSpecification
-  , public virtual submodel::Identifiable
-  , public virtual submodel::Referable
-  , public virtual vab::ElementMap
-{
-public:
-  ~DataSpecification() = default;
-
-  DataSpecification(basyx::object obj);
-
-  // Inherited via IDataSpecification
-  virtual std::shared_ptr<IDataSpecificationContent> getContent() const override;
- 
-  void setContent(const std::shared_ptr<IDataSpecificationContent> & content);
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/dataspecification/DataSpecificationContent.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/dataspecification/DataSpecificationContent.h
deleted file mode 100644
index 2fbfcb2..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/dataspecification/DataSpecificationContent.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * DataSpecificationContent.h
- *
- *      Author: wendel
- */
-
-#ifndef DATASPECIFICATIONCONTENT_H_
-#define DATASPECIFICATIONCONTENT_H_
-
-#include <BaSyx/submodel/api/dataspecification/IDataSpecificationContent.h>
-
-namespace basyx {
-namespace submodel {
-
-
-class DataSpecificationContent
-  : public IDataSpecificationContent
-  , public virtual vab::ElementMap  
-{
-public:
-	using vab::ElementMap::ElementMap;
-
-	DataSpecificationContent() = default;
-	DataSpecificationContent(const IDataSpecificationContent & other);
-
-	~DataSpecificationContent() = default;
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/dataspecification/DataSpecificationIEC61360.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/dataspecification/DataSpecificationIEC61360.h
deleted file mode 100644
index 9f8a99e..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/dataspecification/DataSpecificationIEC61360.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * DataSpecificationIEC61360.h
- *
- *      Author: wendel
- */
-
-#ifndef BASYX_AAS_DATASPECIFICATIONIEC61360_H_
-#define BASYX_AAS_DATASPECIFICATIONIEC61360_H_
-
-#include <BaSyx/submodel/api/dataspecification/IDataSpecificationIEC61360.h>
-
-#include <BaSyx/submodel/map/dataspecification/DataSpecificationContent.h>
-
-//#include <BaSyx/submodel/api/dataspecification/datatypes/LevelType.h>
-
-//#include "datatypes/DataTypeIEC61360.hpp"
-//#include "datatypes/LevelType.hpp"
-
-namespace basyx {
-namespace submodel {
-
-class DataSpecificationIEC61360
-  : public IDataSpecificationIEC61360
-  , public DataSpecificationContent
-  , public virtual vab::ElementMap
-{
-public:
-	using vab::ElementMap::ElementMap;
-	DataSpecificationIEC61360();
-  ~DataSpecificationIEC61360() = default;
-public:
-
-  // Inherited via IDataSpecificationIEC61360
-  virtual std::shared_ptr<ILangStringSet> PreferredName() override;
-  virtual std::shared_ptr<ILangStringSet> ShortName() override;
-  virtual std::string getUnit() const override;
-  virtual std::shared_ptr<submodel::IReference> getUnitId() const override;
-  virtual std::string getSourceOfDefinition() const override;
-  virtual DataTypeIEC61360 getDataType() const override;
-  virtual std::shared_ptr<ILangStringSet> Definition() override;
-  virtual std::string getValueFormat() const override;
-  virtual basyx::object getValueList() const override;
-  virtual std::shared_ptr<submodel::IReference> getValueId() const override;
-  virtual LevelType getLevelType() const override;
-
-//  void setPreferredName(const std::string & preferredName);
-//  void setShortName(const std::string & shortName);
-  void setUnit(const std::string & unit);
-  void setUnitId(const submodel::IReference & unitId);
-  void setSourceOfDefinition(const std::string & sourceOfDefinition);
-  void setDataType(const std::string & dataType);
-//  void setDefinition(const std::string & definition);
-  void setValueFormat(const std::string & valueFormat);
-  void setValueList(const basyx::object & valueList);
-  void setValueId(const IReference & valueId);
-  void setLevelType(const LevelType & levelType);
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/identifier/Identifier.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/identifier/Identifier.h
deleted file mode 100644
index cf33ff6..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/identifier/Identifier.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Identifier.h
- *
- *      Author: wendel
- */
-
-#ifndef AAS_IMPL_METAMODEL_IDENTIFIER_H_
-#define AAS_IMPL_METAMODEL_IDENTIFIER_H_
-
-#include <BaSyx/submodel/api/identifier/IIdentifier.h>
-
-#include <BaSyx/shared/types.h>
-#include <BaSyx/shared/object.h>
-
-#include <BaSyx/vab/ElementMap.h>
-
-namespace basyx {
-namespace submodel {
-
-class Identifier : 
-	public virtual IIdentifier,
-	public virtual vab::ElementMap
-{
-public:
-	~Identifier() = default;
-
-	Identifier();
-	Identifier(const std::string & id, const std::string & idType);
-	Identifier(basyx::object object);
-  Identifier(const std::shared_ptr<IIdentifier> & other);
-  Identifier(const IIdentifier & other);
-
-	// Inherited via IIdentifier
-	virtual std::string getIdType() const override;
-	virtual std::string getId() const override;
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/identifier/IdentifierType.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/identifier/IdentifierType.h
deleted file mode 100644
index 62f0286..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/identifier/IdentifierType.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * IdentifierType.h
- *
- *      Author: wendel
- */
-
-#ifndef AAS_IMPL_METAMODEL_IDENTIFIERTYPE_H_
-#define AAS_IMPL_METAMODEL_IDENTIFIERTYPE_H_
-
-namespace basyx {
-namespace submodel {
-
-struct IdentifierType 
-{
-	  static constexpr char IRDI[] = "IRDI";
-	  static constexpr char URI[] = "URI";
-	  static constexpr char Custom[] = "Custom";
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/modeltype/ModelType.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/modeltype/ModelType.h
deleted file mode 100644
index 41bf674..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/modeltype/ModelType.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Constraint.h
- *
- *      Author: wendel
- */
-
-#ifndef SUBMODEL_SUBMODEL_MAP_MODELTYPE_MODELTYPE_H
-#define SUBMODEL_SUBMODEL_MAP_MODELTYPE_MODELTYPE_H
-
-
-#include <BaSyx/vab/ElementMap.h>
-
-namespace basyx {
-namespace submodel {
-
-class ModelType : public virtual vab::ElementMap {
-public:
-	struct Path {
-		static constexpr char ModelType[] = "modelType";
-		static constexpr char Name[] = "name";
-	};
-public:
-	ModelType();
-	ModelType(const std::string & type);
-//	explicit ModelType(basyx::object object);
-
-    ~ModelType() = default;
-};
-
-}
-}
-
-#endif /* SUBMODEL_SUBMODEL_MAP_MODELTYPE_MODELTYPE_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/parts/ConceptDescription.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/parts/ConceptDescription.h
deleted file mode 100644
index 95bcf9c..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/parts/ConceptDescription.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * ConceptDictionary.h
- *
- *      Author: wendel
- */
-
-#ifndef AAS_IMPL_METAMODEL_HASHMAP_PARTS_CONCEPTDESCRIPTION_H_
-#define AAS_IMPL_METAMODEL_HASHMAP_PARTS_CONCEPTDESCRIPTION_H_
-
-#include <BaSyx/submodel/api/parts/IConceptDescription.h>
-#include <BaSyx/submodel/api/dataspecification/IDataSpecificationIEC61360.h>
-
-#include <BaSyx/submodel/map/qualifier/HasDataSpecification.h>
-#include <BaSyx/submodel/map/qualifier/Identifiable.h>
-#include <BaSyx/submodel/map/modeltype/ModelType.h>
-
-namespace basyx {
-namespace submodel {
-
-class ConceptDescription 
-  : public virtual IConceptDescription
-  , public virtual submodel::HasDataSpecification
-  , public virtual submodel::Identifiable
-  , public virtual submodel::ModelType
-  , public virtual vab::ElementMap
-{
-public:
-	~ConceptDescription() = default;
-
-  ConceptDescription(basyx::object obj);
-  ConceptDescription();
-  ConceptDescription(IConceptDescription & other);
-  
-  void addDataSpecification(const IDataSpecificationIEC61360 & dataSpec) {};
-
-  // Inherited via IConceptDescription
-  virtual basyx::specificCollection_t<submodel::IReference> getIsCaseOf() const override;
-
-  virtual void setIsCaseOf(const basyx::specificCollection_t<submodel::IReference>& references) override;
-
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/qualifier/AdministrativeInformation.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/qualifier/AdministrativeInformation.h
deleted file mode 100644
index c53b81f..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/qualifier/AdministrativeInformation.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * AdministrativeInformation.h
- *
- *      Author: wendel
- */
-
-#ifndef AAS_IMPL_METAMODEL_ADMINISTRATIVEINFORMATION_H_
-#define AAS_IMPL_METAMODEL_ADMINISTRATIVEINFORMATION_H_
-
-#include <BaSyx/submodel/api/qualifier/IAdministrativeInformation.h>
-#include <BaSyx/submodel/map/qualifier/HasDataSpecification.h>
-
-#include <BaSyx/shared/object.h>
-
-#include <BaSyx/vab/ElementMap.h>
-
-namespace basyx {
-namespace submodel {
-
-class AdministrativeInformation :
-	public virtual IAdministrativeInformation,
-	public virtual HasDataSpecification,
-  public virtual vab::ElementMap
-{
-public:
-  ~AdministrativeInformation() = default;
-
-  AdministrativeInformation();
-  AdministrativeInformation(const std::string & version, const std::string & revision);
-  AdministrativeInformation(basyx::object object);
-  AdministrativeInformation(const IAdministrativeInformation & other);
-
-  void setVersion(const std::string & version);
-  void setRevision(const std::string & revision);
-
-  virtual std::string getVersion() const override;
-  virtual std::string getRevision() const override;
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/qualifier/Description.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/qualifier/Description.h
deleted file mode 100644
index e79e0f2..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/qualifier/Description.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Description.h
- *
- *      Author: wendel
- */
-
-#ifndef IMPL_METAMODEL_QUALIFIER_DESCRIPTION_H_
-#define IMPL_METAMODEL_QUALIFIER_DESCRIPTION_H_
-
-#include <BaSyx/vab/ElementMap.h>
-
-#include <BaSyx/shared/types.h>
-#include <BaSyx/shared/object.h>
-
-#include <string>
-
-namespace basyx {
-namespace submodel {
-
-class Description : public vab::ElementMap
-{
-public:
-	struct Path {
-		static constexpr char Language[] = "language";
-		static constexpr char Text[] = "text";
-	};
-public:
-  ~Description() = default;
-
-  Description();
-  Description(const std::string & language, const std::string & text);
-  Description(basyx::object object);
-
-  std::string getLanguage() const;
-  std::string getText() const;
-
-  friend bool operator==(const Description & left, const Description & right);
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/qualifier/HasDataSpecification.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/qualifier/HasDataSpecification.h
deleted file mode 100644
index 4f792eb..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/qualifier/HasDataSpecification.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * HasDataSpecification.h
- *
- *      Author: wendel
- */
-
-#ifndef BASYX_SUBMODEL_METAMODEL_MAP_QUALIFIER_HASDATASPECIFICATION_H_
-#define BASYX_SUBMODEL_METAMODEL_MAP_QUALIFIER_HASDATASPECIFICATION_H_
-
-#include <BaSyx/submodel/api/qualifier/IHasDataSpecification.h>
-#include <BaSyx/submodel/api/reference/IReference.h>
-
-#include <BaSyx/shared/object.h>
-
-#include <BaSyx/vab/ElementMap.h>
-
-namespace basyx {
-namespace submodel {
-
-class HasDataSpecification : 
-	public virtual IHasDataSpecification,
-	public virtual vab::ElementMap
-{
-public:
-	HasDataSpecification();
-	HasDataSpecification(basyx::object & obj);
-	HasDataSpecification(const basyx::specificCollection_t<IReference> & refs);
-	HasDataSpecification(const IHasDataSpecification & hasDataSpecification);
-
-	~HasDataSpecification() = default;
-
-	// Inherited via IHasDataSpecification
-	virtual basyx::specificCollection_t<IReference> getDataSpecificationReferences() const override;
-
-	void setDataSpecificationReferences(const basyx::specificCollection_t<IReference> & references);
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/qualifier/HasKind.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/qualifier/HasKind.h
deleted file mode 100644
index 2aa0d4f..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/qualifier/HasKind.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * HasKind.h
- *
- *      Author: wendel
- */
-
-#ifndef BASYX_SUBMODEL_METAMODEL_MAP_QUALIFIER_KIND_HASKIND_H_
-#define BASYX_SUBMODEL_METAMODEL_MAP_QUALIFIER_KIND_HASKIND_H_
-
-#include <BaSyx/submodel/api/qualifier/IHasKind.h>
-
-#include <BaSyx/vab/ElementMap.h>
-
-namespace basyx {
-namespace submodel {
-
-class HasKind : 
-	public virtual IHasKind, 
-	public virtual basyx::vab::ElementMap
-{
-public:
-	// constructors
-	HasKind(Kind kind = Kind::Instance);
-	HasKind(basyx::object object);
-  HasKind(const IHasKind & other);
-
-	void Init(Kind kind = Kind::Instance);
-
-	~HasKind() = default;
-
-	// Inherited via IHasKind
-	virtual Kind getHasKindReference() const override;
-
-	// not inherited
-	void setHasKindReference(Kind kind);
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/qualifier/HasSemantics.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/qualifier/HasSemantics.h
deleted file mode 100644
index 1a0eb71..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/qualifier/HasSemantics.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * HasSemantics.h
- *
- *      Author: wendel
- */
-
-#ifndef BASYX_SUBMODEL_METAMODEL_MAP_QUALIFIER_HASSEMANTICS_H_
-#define BASYX_SUBMODEL_METAMODEL_MAP_QUALIFIER_HASSEMANTICS_H_
-
-#include <BaSyx/submodel/api/qualifier/IHasSemantics.h>
-#include <BaSyx/submodel/api/reference/IReference.h>
-
-#include <BaSyx/shared/object.h>
-
-#include <BaSyx/vab/ElementMap.h>
-
-namespace basyx {
-namespace submodel {
-
-
-class HasSemantics : 
-	public virtual IHasSemantics,
-	public virtual vab::ElementMap
-{
-public:
-	~HasSemantics() = default;
-
-	HasSemantics();
-	HasSemantics(basyx::object object);
-	HasSemantics(const std::shared_ptr<IReference> & reference);
-  HasSemantics(const IHasSemantics & semantics);
-
-	void setSemanticId(const std::shared_ptr<IReference> & reference);
-	void setSemanticId(const IReference & reference);
-
-	// Inherited via IHasSemantics
-	virtual std::shared_ptr<IReference> getSemanticId() const override;
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/qualifier/Identifiable.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/qualifier/Identifiable.h
deleted file mode 100644
index eb400d7..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/qualifier/Identifiable.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Identifiable.h
- *
- *      Author: wendel
- */
-
-#ifndef BASYX_SUBMODEL_METAMODEL_MAP_QUALIFIER_IDENTIFIABLE_H_
-#define BASYX_SUBMODEL_METAMODEL_MAP_QUALIFIER_IDENTIFIABLE_H_
-
-#include <BaSyx/shared/object.h>
-
-#include <BaSyx/submodel/api/qualifier/IIdentifiable.h>
-#include <BaSyx/submodel/map/qualifier/Referable.h>
-
-namespace basyx {
-namespace submodel {
-
-class Identifiable :
-  public virtual IIdentifiable,
-  public virtual Referable,
-  public virtual vab::ElementMap
-{
-public:
-
-public:
-	~Identifiable() = default;
-
-	// constructors
-	Identifiable();
-	Identifiable(const IIdentifiable & identifiable);
-	Identifiable(const basyx::object & obj);
-	Identifiable(const IIdentifier & identifier, const IAdministrativeInformation & administration);
-	Identifiable(
-		const std::string & version, 
-		const std::string & revision, 
-		const std::string & idShort, 
-		const std::string & category, 
-		const Description & description, 
-		const std::string & idType, 
-		const std::string & id);
-  
-	// Inherited via IIdentifiable
-	virtual std::shared_ptr<IAdministrativeInformation> getAdministration() const override;
-	virtual std::shared_ptr<IIdentifier> getIdentification() const override;
-
-	// not inherited
-	void setAdministration(const IAdministrativeInformation & administration);
-	void setIdentification(const IIdentifier & identification);
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/qualifier/Referable.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/qualifier/Referable.h
deleted file mode 100644
index 24b62af..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/qualifier/Referable.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Referable.h
- *
- *      Author: wendel
- */
-
-#ifndef BASYX_SUBMODEL_METAMODEL_MAP_QUALIFIER_REFERABLE_H_
-#define BASYX_SUBMODEL_METAMODEL_MAP_QUALIFIER_REFERABLE_H_
-
-#include <BaSyx/submodel/api/qualifier/IReferable.h>
-
-#include <BaSyx/shared/object.h>
-
-#include <BaSyx/vab/ElementMap.h>
-
-namespace basyx {
-namespace submodel {
-
-class Referable : 
-	public virtual IReferable,
-	public virtual vab::ElementMap
-{
-public:
-  ~Referable() = default;
-
-  // Constructors
-  Referable();
-  Referable(basyx::object & obj);
-  Referable(const std::string & shortID, const std::string & category, const Description & description);
-  Referable(const IReferable & other);
-
-  // Inherited via IReferable
-  virtual std::string getIdShort() const override;
-  virtual std::string getCategory() const override;
-  virtual Description getDescription() const override;
-  virtual std::shared_ptr<IReference> getParent() const override;
-
-  // not inherited
-  void setIdShort(const std::string & shortID);
-  void setCategory(const std::string & category);
-  void setDescription(const Description & description);
-  void setParent(const IReference & parentReference);
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/qualifier/qualifiable/Constraint.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/qualifier/qualifiable/Constraint.h
deleted file mode 100644
index 431aabb..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/qualifier/qualifiable/Constraint.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Constraint.h
- *
- *      Author: wendel
- */
-
-#ifndef BASYX_SUBMODEL_METAMODEL_MAP_QUALIFIER_QUALIFIABLE_CONSTRAINT_H_
-#define BASYX_SUBMODEL_METAMODEL_MAP_QUALIFIER_QUALIFIABLE_CONSTRAINT_H_
-
-#include <BaSyx/submodel/api/qualifier/qualifiable/IConstraint.h>
-
-#include <BaSyx/vab/ElementMap.h>
-
-namespace basyx {
-namespace submodel {
-
-class Constraint : 
-	public virtual IConstraint,
-	public virtual vab::ElementMap
-{
-public:
-	Constraint();
-	Constraint(basyx::object object);
-	Constraint(const IConstraint & constraint);
-
-	~Constraint() = default;
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/qualifier/qualifiable/Formula.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/qualifier/qualifiable/Formula.h
deleted file mode 100644
index d859eba..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/qualifier/qualifiable/Formula.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Formula.h
- *
- *      Author: wendel
- */
-
-#ifndef BASYX_SUBMODEL_METAMODEL_MAP_QUALIFIER_QUALIFIABLE_FORMULA_H_
-#define BASYX_SUBMODEL_METAMODEL_MAP_QUALIFIER_QUALIFIABLE_FORMULA_H_
-
-#include <BaSyx/submodel/api/qualifier/qualifiable/IFormula.h>
-#include <BaSyx/submodel/map/qualifier/qualifiable/Constraint.h>
-
-namespace basyx {
-namespace submodel {
-
-class Formula 
-  : public virtual Constraint
-  , public IFormula
-  , public virtual vab::ElementMap
-{
-public:
-  ~Formula() = default;
-
-  // constructors
-  Formula();
-  Formula(const basyx::specificCollection_t<IReference> & dependsOn);
-
-  // Inherited via IFormula
-  virtual basyx::specificCollection_t<IReference> getDependsOn() const override;
-
-  // not inherited
-  void setDependsOn(const basyx::specificCollection_t<IReference> & dependsOn);
-
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/qualifier/qualifiable/Qualifiable.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/qualifier/qualifiable/Qualifiable.h
deleted file mode 100644
index 2e9cfe3..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/qualifier/qualifiable/Qualifiable.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Qualifiable.h
- *
- *      Author: wendel
- */
-
-#ifndef BASYX_SUBMODEL_METAMODEL_MAP_QUALIFIER_QUALIFIABLE_QUALIFIABLE_H_
-#define BASYX_SUBMODEL_METAMODEL_MAP_QUALIFIER_QUALIFIABLE_QUALIFIABLE_H_
-
-#include <BaSyx/submodel/api/qualifier/qualifiable/IQualifiable.h>
-
-#include <BaSyx/vab/ElementMap.h>
-
-namespace basyx {
-namespace submodel {
-
-class Qualifiable :
-	public virtual IQualifiable,
-	public virtual vab::ElementMap
-{
-public:
-	~Qualifiable() = default;
-
-	// constructors
-	Qualifiable();
-  Qualifiable(const std::shared_ptr<IQualifiable> & other);
-  Qualifiable(const IQualifiable & other);
-	Qualifiable(basyx::object object);
-	Qualifiable(const std::shared_ptr<IConstraint> & constraint);
-	Qualifiable(const basyx::specificCollection_t<IConstraint> & constraints);
-
-	// Inherited via IQualifiable
-	virtual basyx::specificCollection_t<IConstraint> getQualifier() const override;
-
-	// not inherited
-	void setQualifier(const basyx::specificCollection_t<IConstraint> & qualifiers);
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/qualifier/qualifiable/Qualifier.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/qualifier/qualifiable/Qualifier.h
deleted file mode 100644
index 4b17eeb..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/qualifier/qualifiable/Qualifier.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Qualifier.h
- *
- *      Author: wendel
- */
-
-#ifndef BASYX_SUBMODEL_METAMODEL_MAP_QUALIFIER_QUALIFIABLE_QUALIFIER_H_
-#define BASYX_SUBMODEL_METAMODEL_MAP_QUALIFIER_QUALIFIABLE_QUALIFIER_H_
-
-#include <BaSyx/submodel/map/qualifier/qualifiable/Constraint.h>
-#include <BaSyx/submodel/api/qualifier/qualifiable/IQualifier.h>
-#include <BaSyx/submodel/map/qualifier/HasSemantics.h>
-#include <BaSyx/shared/object.h>
-
-namespace basyx {
-namespace submodel {
-
-class Qualifier 
-  : public Constraint
-  , public virtual IQualifier
-  , public virtual HasSemantics
-  , public virtual basyx::vab::ElementMap
-{
-public:
-  ~Qualifier() = default;
-
-  // constructors
-  Qualifier();
-  Qualifier(
-	  const std::string & qualifierType, 
-	  const basyx::object & qualifierValue, 
-	  const IReference & valueId);
-
-  // Inherited via IQualifier
-  virtual std::string getQualifierType() const override;
-  virtual basyx::object getQualifierValue() const override;
-  virtual std::shared_ptr<IReference> getQualifierValueId() const override;
-
-  // not inherited
-  void setQualifierType(const std::string & qualifierType);
-  void setQualifierValue(const basyx::object & qualifierValue);
-  void setQualifierValueId(const IReference & valueId);
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/qualifier/qualifiable/QualifierType.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/qualifier/qualifiable/QualifierType.h
deleted file mode 100644
index 7bc80c8..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/qualifier/qualifiable/QualifierType.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * QualifierType.h
- *
- *      Author: wendel
- */
-
-#ifndef BASYX_SUBMODEL_METAMODEL_MAP_QUALIFIER_QUALIFIABLE_QUALIFIERTYPE_H_
-#define BASYX_SUBMODEL_METAMODEL_MAP_QUALIFIER_QUALIFIABLE_QUALIFIERTYPE_H_
-
-namespace basyx {
-namespace submodel {
-
-class QualifierType
-{
-public:
-  ~QualifierType() = default;
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/reference/Key.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/reference/Key.h
deleted file mode 100644
index 8f4e129..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/reference/Key.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Key.h
- *
- *      Author: wendel
- */
-
-#ifndef AAS_IMPL_METAMODEL_HASHMAP_REFERENCE_KEY_H_
-#define AAS_IMPL_METAMODEL_HASHMAP_REFERENCE_KEY_H_
-
-
-#include <BaSyx/submodel/api/reference/IKey.h>
-
-#include <BaSyx/shared/object.h>
-
-#include <BaSyx/vab/ElementMap.h>
-
-namespace basyx {
-namespace submodel {
-
-class Key 
-  : public IKey
-  , public virtual vab::ElementMap
-{
-public:
-	struct KeyType {
-		static constexpr char IRDI[] = "IRDI";
-	};
-
-	struct KeyElements {
-		static constexpr char ConceptDictionary[] = "ConceptDictionary";
-	};
-public:
-	virtual ~Key() = default;
-
-	//constructor 
-	Key(const std::string & type, const bool & local, const std::string & value, const std::string & idType);
-  Key(basyx::object obj);
-
-	// Inherited via IKey
-	virtual std::string getType() const override;
-	virtual bool isLocal() const override;
-	virtual std::string getValue() const override;
-	virtual std::string getidType() const override;
-
-	// not inherited
-	void setType(const std::string & type);
-	void setLocal(const bool & local);
-	void setValue(const std::string & value);
-	void setIdType(const std::string & idType);
-
-  friend bool operator==(const IKey & left, const IKey & right);
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/reference/Reference.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/reference/Reference.h
deleted file mode 100644
index b3cf36d..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/reference/Reference.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Reference.h
- *
- *      Author: wendel
- */
-
-#ifndef AAS_IMPL_METAMODEL_HASHMAP_REFERENCE_H_
-#define AAS_IMPL_METAMODEL_HASHMAP_REFERENCE_H_
-
-#include <BaSyx/submodel/api/reference/IReference.h>
-
-#include <BaSyx/submodel/map/reference/Key.h>
-#include <BaSyx/submodel/api/qualifier/IIdentifiable.h>
-
-#include <BaSyx/shared/object.h>
-
-#include <BaSyx/vab/ElementMap.h>
-
-namespace basyx {
-namespace submodel {
-
-class Reference : 
-	public IReference,
-	public vab::ElementMap
-{
-public:
-	using vab::ElementMap::ElementMap;
-
-	virtual ~Reference() = default;
-
-	Reference();
-	Reference(const basyx::specificCollection_t<IKey> & keys);
-	Reference(const std::initializer_list<Key> keys);
-	Reference(const IReference & reference);
-
-	// Inherited via IReference
-	virtual const basyx::specificCollection_t<IKey> getKeys() const override;
-	virtual void setKeys(const basyx::specificCollection_t<IKey> & keys) override;
-public:
-	static Reference FromIdentifiable(const std::string & keyElementType, bool local, const IIdentifiable & identifiable);
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/DataElement.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/DataElement.h
deleted file mode 100644
index 0d0e40f..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/DataElement.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * DataElement.h
- *
- *      Author: wendel
- */
-
-#ifndef IMPL_METAMODEL_MAP_AAS_SUBMODELELEMENT_DATAELEMENT_H_
-#define IMPL_METAMODEL_MAP_AAS_SUBMODELELEMENT_DATAELEMENT_H_
-
-#include <BaSyx/submodel/map/submodelelement/SubmodelElement.h>
-#include <BaSyx/submodel/api/submodelelement/IDataElement.h>
-
-namespace basyx {
-namespace submodel {
-
-class DataElement :
-  public virtual vab::ElementMap,
-	public virtual SubmodelElement, 
-	public virtual IDataElement
-{
-public:
-	~DataElement() = default;
-
-	// constructors
-	DataElement();
-	DataElement(basyx::object object);
-  DataElement(const IDataElement & other);
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/ReferenceElement.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/ReferenceElement.h
deleted file mode 100644
index 32c3a5e..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/ReferenceElement.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * ReferenceElement.h
- *
- *      Author: wendel
- */
-
-#ifndef IMPL_METAMODEL_MAP_AAS_SUBMODELELEMENT_REFERENCEELEMENT_H_
-#define IMPL_METAMODEL_MAP_AAS_SUBMODELELEMENT_REFERENCEELEMENT_H_
-
-#include <BaSyx/submodel/map/submodelelement/DataElement.h>
-#include <BaSyx/submodel/api/submodelelement/IReferenceElement.h>
-
-namespace basyx {
-namespace submodel {
-
-class ReferenceElement : 
-  public virtual vab::ElementMap, 
-  public DataElement, 
-  public IReferenceElement
-{
-public:
-  ~ReferenceElement() = default;
-
-  // construtors
-  ReferenceElement();
-  ReferenceElement(const IReference & reference);
-  ReferenceElement(const basyx::object & map);
-
-  // Inherited via IReferenceElement
-  virtual void setValue(const IReference & ref);
-  virtual std::shared_ptr<IReference> getValue() const override;
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/RelationshipElement.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/RelationshipElement.h
deleted file mode 100644
index cc8e4b5..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/RelationshipElement.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * RelationshipElement.h
- *
- *      Author: wendel
- */
-
-#ifndef IMPL_METAMODEL_MAP_AAS_SUBMODELELEMENT_RELATIONSHIPELEMENT_H_
-#define IMPL_METAMODEL_MAP_AAS_SUBMODELELEMENT_RELATIONSHIPELEMENT_H_
-
-#include <BaSyx/submodel/api/submodelelement/ISubmodelElement.h>
-#include <BaSyx/submodel/api/submodelelement/IRelationshipElement.h>
-#include <BaSyx/submodel/api/reference/IReference.h>
-#include <BaSyx/submodel/map/submodelelement/SubmodelElement.h>
-
-namespace basyx {
-namespace submodel {
-
-class RelationshipElement : 
-	public virtual vab::ElementMap,
-	public virtual SubmodelElement,
-	public virtual IRelationshipElement
-{
-public:
-	~RelationshipElement() = default;
-
-	//constructors
-	RelationshipElement();
-	RelationshipElement(const IReference & first, const IReference & second);
-
-	// Inherited via IRelationshipElement
-	virtual void setFirst(const IReference & first) override;
-	virtual std::shared_ptr<IReference> getFirst() const override;
-	virtual void setSecond(const IReference & second) override;
-	virtual std::shared_ptr<IReference> getSecond() const override;
-};
-
-}
-}
-
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/SubmodelElement.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/SubmodelElement.h
deleted file mode 100644
index 82d4889..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/SubmodelElement.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * SubmodelElement.h
- *
- *      Author: wendel
- */
-
-#ifndef IMPL_METAMODEL_MAP_AAS_SUBMODELELEMENT_SUBMODELELEMENT_H_
-#define IMPL_METAMODEL_MAP_AAS_SUBMODELELEMENT_SUBMODELELEMENT_H_
-
-#include <BaSyx/submodel/api/submodelelement/ISubmodelElement.h>
-
-#include <BaSyx/submodel/map/qualifier/HasKind.h>
-#include <BaSyx/submodel/map/qualifier/HasDataSpecification.h>
-#include <BaSyx/submodel/map/qualifier/HasSemantics.h>
-#include <BaSyx/submodel/map/qualifier/Referable.h>
-#include <BaSyx/submodel/map/qualifier/qualifiable/Qualifiable.h>
-#include <BaSyx/submodel/map/modeltype/ModelType.h>
-
-#include <BaSyx/vab/ElementMap.h>
-
-namespace basyx {
-namespace submodel {
-
-class SubmodelElement :
-  public virtual vab::ElementMap,
-	public virtual ModelType,
-	public virtual HasDataSpecification,
-	public virtual HasKind,
-	public virtual HasSemantics,
-	public virtual Qualifiable,
-	public virtual Referable,
-	public virtual ISubmodelElement
-{
-public:
-	~SubmodelElement() = default;
-
-	// constructors
-	SubmodelElement();
-
-	using vab::ElementMap::ElementMap;
-
-	/**
-	* Constructs an SubmodelElement object from a map given that the map contains all required elements.
-	* 
-	* @param submodelElementMap the map representig the submodel.
-	*/
-//	SubmodelElement(basyx::object object);
-
-  SubmodelElement(const ISubmodelElement & abstractSubmodelElement);
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/SubmodelElementCollection.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/SubmodelElementCollection.h
deleted file mode 100644
index f27ceff..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/SubmodelElementCollection.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * SubmodelElementCollection.h
- *
- *      Author: wendel
- */
-
-#ifndef IMPL_METAMODEL_MAP_AAS_SUBMODELELEMENT_SUBMODELELEMENTCOLLECTION_H_
-#define IMPL_METAMODEL_MAP_AAS_SUBMODELELEMENT_SUBMODELELEMENTCOLLECTION_H_
-
-#include <BaSyx/submodel/map/submodelelement/SubmodelElement.h>
-#include <BaSyx/submodel/api/submodelelement/ISubmodelElementCollection.h>
-
-namespace basyx {
-namespace submodel {
-
-class SubmodelElementCollection :
-  public virtual vab::ElementMap,
-	public SubmodelElement, 
-	public ISubmodelElementCollection
-{
-private:
-	virtual void setOrdered(const bool & value);
-	virtual void setAllowDuplicates(const bool & value);
-public:
-	~SubmodelElementCollection() = default;
-
-	// constructors
-	/**
-	* Default constructor, sets ordered and allowDuplicates to false.
-	*/
-	SubmodelElementCollection();
-
-	/**
-	* @param value
-	*            Submodel element contained in the collection
-	* @param ordered
-	*            If ordered=false then the elements in the property collection are
-	*            not ordered. If ordered=true then the elements in the collection
-	*            are ordered.
-	* @param allowDuplicates
-	*            If allowDuplicates=true then it is allowed that the collection
-	*            contains the same element several times
-	*/
-	SubmodelElementCollection(const basyx::specificCollection_t<ISubmodelElement> & value, const bool ordered, const bool allowDuplicates);
-
-	virtual void setValue(const basyx::specificCollection_t<ISubmodelElement> & value);
-	virtual void setElements(const basyx::specificMap_t<ISubmodelElement> & value);
-
-	virtual basyx::specificCollection_t<ISubmodelElement> getValue() const override;
-	virtual bool isOrdered() const override;
-	virtual bool isAllowDuplicates() const override;
-	virtual basyx::specificMap_t<ISubmodelElement> getElements() const override;
-
-	virtual void addSubmodelElement(const ISubmodelElement & element);
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/entity/Entity.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/entity/Entity.h
deleted file mode 100644
index e2857d7..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/entity/Entity.h
+++ /dev/null
@@ -1,40 +0,0 @@
-#ifndef BASYX_METAMODEL_MAP_ENTITY_H_
-#define BASYX_METAMODEL_MAP_ENTITY_H_
-
-#include <BaSyx/submodel/api/submodelelement/entity/IEntity.h>
-#include <BaSyx/submodel/map/submodelelement/SubmodelElement.h>
-
-namespace basyx {
-namespace submodel {
-
-
-class Entity 
-	: public virtual IEntity
-	, public virtual SubmodelElement
-{
-public:
-	Entity(EntityType entityType = EntityType::SelfManagedEntity);
-	Entity(basyx::object object);
-	Entity(const IEntity & entity);
-
-	virtual ~Entity() = default;
-public:
-	virtual basyx::specificCollection_t<ISubmodelElement> getStatements() override;
-
-	virtual EntityType getEntityType() const override;
-
-	virtual std::shared_ptr<IReference> getAsset() const override;
-};
-
-
-}
-}
-
-
-
-
-
-
-
-#endif
-
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/langstring/LangStringSet.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/langstring/LangStringSet.h
deleted file mode 100644
index 9bf839a..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/langstring/LangStringSet.h
+++ /dev/null
@@ -1,37 +0,0 @@
-#ifndef _LANGSTRINGSET_H
-#define _LANGSTRINGSET_H
-
-#include <BaSyx/submodel/api/submodelelement/langstring/ILangStringSet.h>
-
-#include <BaSyx/shared/object.h>
-
-#include <BaSyx/vab/ElementMap.h>
-
-#include <string>
-#include <initializer_list>
-
-namespace basyx {
-namespace submodel {
-
-class LangStringSet 
-	: public ILangStringSet
-	, public virtual vab::ElementMap
-{
-public:
-	using langCodeSet_t = const std::vector<std::reference_wrapper<const std::string>>;
-public:
-	using vab::ElementMap::ElementMap;
-
-	LangStringSet();
-	LangStringSet(std::initializer_list<std::pair<std::string, std::string>> il);
-
-	langCodeSet_t getLanguageCodes() const;
-
-    const std::string & getLangString(const std::string & languageCode) const;
-    void addLangString(const std::string & languageCode, const std::string & langString);
-};
-
-}
-}
-
-#endif /* _LANGSTRINGSET_H */
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/operation/Operation.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/operation/Operation.h
deleted file mode 100644
index 9b76cec..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/operation/Operation.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Operation.h
- *
- *      Author: wendel
- */
-
-#ifndef SUBMODEL_METAMODEL_SUBMODELEMENT_OPERATION_OPERATION_H_
-#define SUBMODEL_METAMODEL_SUBMODELEMENT_OPERATION_OPERATION_H_
-
-#include <BaSyx/shared/object.h>
-#include <BaSyx/shared/types.h>
-
-#include <BaSyx/submodel/api/submodelelement/operation/IOperationVariable.h>
-#include <BaSyx/submodel/api/submodelelement/operation/IOperation.h>
-#include <BaSyx/submodel/map/submodelelement/SubmodelElement.h>
-#include <BaSyx/submodel/map/submodelelement/operation/OperationVariable.h>
-
-
-namespace basyx {
-namespace submodel {
-
-class Operation : 
-	public virtual SubmodelElement, 
-	public virtual IOperation
-{
-public:
-	using Path = IOperation::Path;
-public:
-	~Operation() = default;
-
-	// constructors
-	Operation();
-	Operation(const IOperation & other);
-	Operation(const basyx::object & obj);
-	
-	// Inherited via IOperation
-	virtual basyx::specificCollection_t<IOperationVariable> getParameterTypes() const override;
-	virtual std::shared_ptr<IOperationVariable> getReturnType() const override;
-	virtual basyx::object getInvocable() const override;
-
-	// not inherited
-	void setParameterTypes(const basyx::specificCollection_t<IOperationVariable> & parameterTypes);
-	void setReturnTypes(const std::shared_ptr<IOperationVariable> & returnTypes);
-	void setInvocable(basyx::object invocable);
-
-	// helper methods
-	template<typename T>
-	void addParameter(const std::string & name)
-	{
-		OperationVariable op_var;
-		op_var.setIdShort(name);
-		op_var.setType(util::to_string<basyx::type::basyx_type<T>::value_type>());
-		this->map.getProperty(Path::Input).insert(op_var.getMap());
-	};
-
-	template<typename T>
-	void setReturnType(const std::string & name)
-	{
-		OperationVariable ret_var;
-		ret_var.setIdShort(name);
-		ret_var.setType(util::to_string<basyx::type::basyx_type<T>::value_type>());
-		this->map.insertKey(Path::Output, ret_var.getMap(), true);
-	};
-
-	virtual basyx::object invoke(basyx::object & parameters) const override;
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/operation/OperationVariable.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/operation/OperationVariable.h
deleted file mode 100644
index bf36317..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/operation/OperationVariable.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * ModelType.h
- *
- *      Author: wendel
- */
-
-#ifndef SUBMODEL_METAMODEL_SUBMODELEMENT_OPERATION_OPERATIONVARIABLE_H_
-#define SUBMODEL_METAMODEL_SUBMODELEMENT_OPERATION_OPERATIONVARIABLE_H_
-
-#include <BaSyx/submodel/api/submodelelement/operation/IOperationVariable.h>
-#include <BaSyx/submodel/map/submodelelement/SubmodelElement.h>
-
-#include <BaSyx/shared/object.h>
-
-namespace basyx {
-namespace submodel {
-
-class OperationVariable : 
-	public virtual SubmodelElement, 
-	public virtual IOperationVariable
-{
-public:
-	using Path = IOperationVariable::Path;
-public:
-	~OperationVariable() = default;
-	
-	// constructors
-	OperationVariable();
-	OperationVariable(basyx::object object);
-
-	// Inherited via IOperationVariable
-	virtual std::shared_ptr<ISubmodelElement> getValue() const override;
-	virtual std::string getType() const override;
-	                                                                        
-	// not inherited
-	void setValue(const SubmodelElement & value);
-
-	void setValue(const ISubmodelElement & value);
-	void setType(const std::string & string);
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/property/Blob.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/property/Blob.h
deleted file mode 100644
index 33def54..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/property/Blob.h
+++ /dev/null
@@ -1,47 +0,0 @@
-#ifndef SUBMODEL_METAMODEL_SUBMODELEMENT_BLOB_H_
-#define SUBMODEL_METAMODEL_SUBMODELEMENT_BLOB_H_
-
-#include <BaSyx/shared/object.h>
-#include <BaSyx/shared/types.h>
-
-#include <BaSyx/submodel/api/submodelelement/property/blob/IBlob.h>
-#include <BaSyx/submodel/map/submodelelement/SubmodelElement.h>
-#include <BaSyx/submodel/map/submodelelement/DataElement.h>
-
-
-namespace basyx {
-namespace submodel {
-
-class Blob :
-	public virtual IBlob,
-	public virtual ModelType,
-	public virtual DataElement,
-	public virtual vab::ElementMap
-{
-public:
-	using Path = IBlob::Path;
-public:
-	Blob() : ModelType{Path::ModelType}
-	{
-		map.insertKey(Path::Value, basyx::object::make_null());
-	};
-
-	Blob(const IBlob & other) 
-		: ModelType{Path::ModelType}
-		, vab::ElementMap{}
-	{
-	}
-
-	virtual const std::string & getValue() const override;
-	virtual const std::string & getMimeType() const override;
-
-	void setValue(const std::string & bytes);
-	void setValue(const char * c, std::size_t length);
-
-	void setMimeType(const std::string & mimeType);
-};
-
-}
-}
-
-#endif
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/property/File.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/property/File.h
deleted file mode 100644
index 2d09b52..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/property/File.h
+++ /dev/null
@@ -1,33 +0,0 @@
-#ifndef SUBMODEL_METAMODEL_SUBMODELEMENT_PROPERTY_H_
-#define SUBMODEL_METAMODEL_SUBMODELEMENT_PROPERTY_H_
-
-#include <BaSyx/shared/object.h>
-#include <BaSyx/shared/types.h>
-
-#include <BaSyx/submodel/api/submodelelement/property/file/IFile.h>
-#include <BaSyx/submodel/api/submodelelement/property/ISingleProperty.h>
-#include <BaSyx/submodel/map/submodelelement/SubmodelElement.h>
-#include <BaSyx/submodel/map/submodelelement/DataElement.h>
-
-
-namespace basyx {
-namespace submodel {
-
-class File :
-	public virtual IFile,
-	public virtual ModelType,
-	public virtual DataElement,
-	public virtual vab::ElementMap
-{
-public:
-	virtual const std::string & getValue() const override;
-	virtual const std::string & getMimeType() const override;
-
-	void setValue(const std::string & bytes);
-	void setMimeType(const std::string & mimeType);
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/property/Property.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/property/Property.h
deleted file mode 100644
index eb7d256..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/property/Property.h
+++ /dev/null
@@ -1,105 +0,0 @@
-#ifndef SUBMODEL_METAMODEL_SUBMODELEMENT_PROPERTY_H_
-#define SUBMODEL_METAMODEL_SUBMODELEMENT_PROPERTY_H_
-
-#include <BaSyx/shared/object.h>
-#include <BaSyx/shared/types.h>
-
-#include <BaSyx/submodel/api/submodelelement/property/IProperty.h>
-#include <BaSyx/submodel/api/submodelelement/property/ISingleProperty.h>
-#include <BaSyx/submodel/map/submodelelement/SubmodelElement.h>
-#include <BaSyx/submodel/map/submodelelement/DataElement.h>
-
-
-namespace basyx {
-namespace submodel {
-
-template<typename T>
-class Property : 
-	public virtual ISingleProperty,
-	public virtual DataElement,
-	public virtual vab::ElementMap
-{
-public:
-	using Path = IProperty::Path;
-public:
-	using vab::ElementMap::ElementMap;
-
-  Property() : ModelType{Path::ModelType}
-	{
-		map.insertKey(Path::Value, basyx::object::make_null());
-		map.insertKey(Path::ValueId, basyx::object::make_null());
-	};
-
-  Property(const IProperty & other) :
-    ModelType{Path::ModelType},
-    DataElement{other}
-  {
-    //this->setValue(other.getValue());
-    this->setValueId(other.getValueId());
-  }
-
-	T & getValue()
-	{
-		return map.getProperty(Path::Value).Get<T&>();
-	};
-
-	void setValue(const T & t)
-	{
-		map.insertKey(Path::Value, t, true);
-		//map.insertKey(Path::ValueType, util::from_string<basyx::type::basyx_type<T>::value_type>());
-	};
-
-	basyx::object get()
-	{
-		return map.getProperty(Path::Value);
-	};
-
-	void set(const basyx::object & object)
-	{
-		if (!object.InstanceOf<T>())
-		{
-			map.insertKey(Path::Value, basyx::object::make_null(), true);
-			//map.insertKey(Path::ValueType, util::from_string<basyx::type::valueType::Null>(), true);
-		}
-		else
-		{
-			map.insertKey(Path::Value, object, true);
-			//map.insertKey(Path::ValueType, util::from_string<basyx::type::basyx_type<T>::value_type>(), true);
-		}
-	};
-
-	const T & getValue() const
-	{
-		return map.getProperty(Path::Value).Get<T&>();
-	};
-
-	// Inherited via ISingleProperty
-	virtual PropertyType getPropertyType() const override
-	{
-		return PropertyType();
-	}
-
-	virtual void setValueId(const std::string & valueId) override
-	{
-	}
-
-	virtual std::string getValueId() const override
-	{
-		return std::string();
-	}
-
-	virtual basyx::object get() const override
-	{
-		return basyx::object();
-	}
-
-	virtual std::string getValueType() const override
-	{
-		return std::string();
-	}
-};
-
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/property/valuetypedef/PropertyValueTypeDef.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/property/valuetypedef/PropertyValueTypeDef.h
deleted file mode 100644
index 642201a..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/property/valuetypedef/PropertyValueTypeDef.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * PropertyValueTypeDef.h
- *
- *      Author: wendel
- */
-
-#ifndef AAS_IMPL_SUBMODELELEMENT_PROPERTY_VALUETYPEDEF_PROPERTYVALUETYPEDEF_H_
-#define AAS_IMPL_SUBMODELELEMENT_PROPERTY_VALUETYPEDEF_PROPERTYVALUETYPEDEF_H_
-
-namespace basyx {
-namespace submodel {
-namespace impl {
-namespace metamodel {
-
-namespace PropertyValueTypeDef {
-  static constexpr char Double[] = "double";
-  static constexpr char Float[] = "float";
-  static constexpr char Integer[] = "int";
-  static constexpr char String[] = "string";
-  static constexpr char Boolean[] = "boolean";
-  static constexpr char Map[] = "map";
-  static constexpr char Collection[] = "collection";
-  static constexpr char Void[] = "void";
-  static constexpr char Null[] = "null";
-  static constexpr char Container[] = "container";
-}
-
-namespace PropertyValueTypeIdentifier {
-  static constexpr char TYPE_NAME[] = "name";
-  static constexpr char TYPE_OBJECT[] = "dataObjectType";
-}
-
-}
-}
-}
-}
-
-#endif
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/property/valuetypedef/PropertyValueTypeDefHelper.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/property/valuetypedef/PropertyValueTypeDefHelper.h
deleted file mode 100644
index 0263161..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map/submodelelement/property/valuetypedef/PropertyValueTypeDefHelper.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * PropertyValueTypeDefHelper.h
- *
- *      Author: wendel
- */
-
-#ifndef AAS_IMPL_SUBMODELELEMENT_PROPERTY_VALUETYPEDEF_PROPERTYVALUETYPEDEFHELPER_H_
-#define AAS_IMPL_SUBMODELELEMENT_PROPERTY_VALUETYPEDEF_PROPERTYVALUETYPEDEFHELPER_H_
-
-#include "PropertyValueTypeDef.h"
-
-namespace basyx {
-namespace submodel {
-namespace impl {
-namespace metamodel {
-
-class PropertyValueTypeDefHelper
-{
-public:
-  ~PropertyValueTypeDefHelper();
-
-private:
-
-};
-
-}
-}
-}
-}
-
-#endif
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/SubModel.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/SubModel.h
index 559fad8..824668c 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/SubModel.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/SubModel.h
@@ -21,7 +21,6 @@
 namespace submodel {
 namespace map {
 
-
 class SubModel : 
 	public virtual api::ISubModel,
 	public Identifiable,
@@ -30,6 +29,12 @@
 	public ModelType<ModelTypes::Submodel>,
 	public virtual vab::ElementMap
 {
+public:
+  struct Path {
+    static constexpr char SubmodelElements[] = "submodelElements";
+    static constexpr char SemanticId[] = "semanticId";
+    static constexpr char Kind[] = "kind";
+  };
 private:
 	Reference semanticId;
 	ElementContainer<api::ISubmodelElement> elementContainer;
@@ -47,6 +52,8 @@
 	// Inherited via IHasSemantics
 	virtual const api::IReference & getSemanticId() const override;
 	virtual void setSemanticId(const api::IReference & semanticId) override;
+
+	virtual KeyElements getKeyElementType() const override { return KeyElements::Submodel; };
 };
 
 
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/aas/Asset.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/aas/Asset.h
index dd55fcd..511959d 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/aas/Asset.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/aas/Asset.h
@@ -19,6 +19,12 @@
 	public map::ModelType<ModelTypes::Asset>,
 	public virtual vab::ElementMap
 {
+public:
+  struct Path {
+    static constexpr char Kind[] = "kind";
+    static constexpr char AssetIdentificationModelRef[] = "assetIdentificationModelRef";
+    static constexpr char BillOfMaterialRef[] = "billOfMaterialRef";
+  };
 private:
 	Reference assetIdentificationModelRef;
 	Reference billOfMaterialRef;
@@ -27,13 +33,15 @@
 	Asset(const std::string & idShort, const simple::Identifier & identifier, AssetKind kind = AssetKind::Instance);
 	virtual ~Asset() = default;
 
-	virtual AssetKind getKind();
+	virtual AssetKind getKind() override;
 
 	virtual api::IReference * const getAssetIdentificationModel() override;
 	virtual void setAssetIdentificationModel(const api::IReference & assetIdentificationModelRef) override;
 
 	virtual api::IReference * const getBillOfMaterial() override;
 	virtual void setBillOfMaterial(const api::IReference & billOfMaterialRef) override;
+
+	virtual KeyElements getKeyElementType() const override { return KeyElements::Asset; };
 };
 
 }
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/aas/AssetAdministrationShell.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/aas/AssetAdministrationShell.h
index 5174146..34a467d 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/aas/AssetAdministrationShell.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/aas/AssetAdministrationShell.h
@@ -22,6 +22,11 @@
 	public map::ModelType<ModelTypes::AssetAdministrationShell>,
 	public virtual vab::ElementMap
 {
+public:
+  struct Path {
+    static constexpr char Submodels[] = "submodels";
+    static constexpr char Asset[] = "asset";
+  };
 private:
 	Reference derivedFrom;
 	Asset asset;
@@ -39,6 +44,8 @@
 	virtual api::IReference * getDerivedFrom() override;
 	virtual void setDerivedFrom(const api::IReference & reference) override;
 	virtual SubmodelContainer_t & getSubmodels() override;
+
+	virtual KeyElements getKeyElementType() const override { return KeyElements::AssetAdministrationShell; };
 };
 
 }
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/common/ElementContainer.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/common/ElementContainer.h
index 5739f81..f6700cc 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/common/ElementContainer.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/common/ElementContainer.h
@@ -5,6 +5,7 @@
 #include <BaSyx/submodel/map_v2/common/ElementFactory.h>
 #include <BaSyx/submodel/map_v2/qualifier/Referable.h>
 #include <BaSyx/submodel/map_v2/qualifier/Identifiable.h>
+#include <BaSyx/submodel/map_v2/reference/Reference.h>
 #include <BaSyx/submodel/map_v2/submodelelement/SubmodelElementFactory.h>
 #include <BaSyx/vab/ElementMap.h>
 
@@ -15,6 +16,10 @@
 namespace submodel {
 namespace map {
 
+struct ElementContainerPath {
+	static constexpr char IdShort[] = "idShort";
+};
+
 template<typename IElementType>
 class ElementContainer : public api::IElementContainer<IElementType>, public virtual vab::ElementMap
 {
@@ -22,20 +27,29 @@
     using elementPtr_t = typename api::IElementContainer<IElementType>::elementPtr_t;
     using cache_t = std::unordered_map<std::string, elementPtr_t>;
 private:
+	api::IReferable * parent;
 	mutable cache_t cache;
+	basyx::object keyList;
 public:
 	using vab::ElementMap::ElementMap;
-	ElementContainer()
-		: vab::ElementMap(basyx::object::make_object_list())
+	ElementContainer(api::IReferable * parent = nullptr)
+		: vab::ElementMap(basyx::object::make_map())
+		, keyList(basyx::object::make_object_list())
+		, parent(parent)
 	{
 	};
 
 	virtual ~ElementContainer() = default;
 public:
+	basyx::object getKeyMap() { return this->keyList; };
+public:
 	virtual std::size_t size() const override;
+	virtual api::IReferable * getParent() const override;
+
 	virtual IElementType * const getElement(const std::string & idShort) const override;
 	virtual IElementType * const getElement(std::size_t n) const override;
 	virtual void addElement(elementPtr_t element) override;
+//	virtual std::vector<simple::Identifier> getIdentifierList();
 };
 
 template<typename IElementType>
@@ -45,20 +59,19 @@
 };
 
 template<typename IElementType>
+api::IReferable * ElementContainer<IElementType>::getParent() const
+{
+	return this->parent;
+};
+
+template<typename IElementType>
 IElementType * const ElementContainer<IElementType>::getElement(const std::string & idShort) const
 {
 	// Find element in object tree
-	auto & objectList = this->getMap().template Get<basyx::object::object_list_t&>();
-
-	auto objectIterator = std::find_if(
-		objectList.begin(), objectList.end(),
-		[&idShort](basyx::object & obj) {
-		const auto & id = obj.getProperty(map::Identifiable::Path::IdShort).Get<std::string&>();
-		return idShort == id;
-	});
+	auto && object = this->map.getProperty(idShort);
 
 	// element doesn't exist, remove from cache and return nullptr
-	if (objectIterator == objectList.end()) {
+	if (object.IsNull() || object.IsError()) {
 		this->cache.erase(idShort);
 		return nullptr;
 	}
@@ -67,7 +80,7 @@
 		auto element = cache.find(idShort);
 		if (element == cache.end()) {
 			// not in cache, re-create elementPtr and return
-			elementPtr_t elementPtr = ElementFactory<IElementType>::Create(vab::ElementMap(*objectIterator));
+			elementPtr_t elementPtr = ElementFactory<IElementType>::Create(vab::ElementMap(object));
 			auto ptr = this->cache.emplace(idShort, std::move(elementPtr));
 			ptr.first->second.get();
 		}
@@ -85,13 +98,20 @@
 	if (n > this->size())
 		return nullptr;
 
-	// Find element in object tree
-	auto & objectList = this->getMap().template Get<basyx::object::object_list_t&>();
-	auto & obj = objectList.at(n);
+	// Iterate through object map
+	int i = 0;
+	
+	for(const auto & entry : map.Get<basyx::object::object_map_t&>())
+	{
+		if (i++ == n)
+		{
+			// Get id of object and create temporary
+			const auto & id = entry.first;
+			return this->getElement(id);
+		};
+	};
 
-	// Get id of object and create temporary
-	const auto & id = obj.getProperty(map::Identifiable::Path::IdShort).Get<std::string&>();
-	return this->getElement(id);
+	return nullptr;
 };
 
 
@@ -103,7 +123,11 @@
 	auto elementMap = dynamic_cast<vab::ElementMap*>(element.get());
 	if (elementMap != nullptr)
 	{
-		this->map.insert(elementMap->getMap());
+		// Get reference from element
+		map::Reference reference(element->getReference());
+
+		this->keyList.insert(reference.getMap());
+		this->map.insertKey(shortId, elementMap->getMap());
 		this->cache.emplace(shortId, std::move(element));
 	};
 };
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/common/ElementFactory.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/common/ElementFactory.h
index 9019107..ed3755a 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/common/ElementFactory.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/common/ElementFactory.h
@@ -31,4 +31,4 @@
 }
 
 
-#endif /* BASYX_SUBMODEL_MAP_V2_COMMON_ELEMENTFACTORY_H */
\ No newline at end of file
+#endif /* BASYX_SUBMODEL_MAP_V2_COMMON_ELEMENTFACTORY_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/common/ModelType.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/common/ModelType.h
index 71f19d2..6151372 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/common/ModelType.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/common/ModelType.h
@@ -8,6 +8,11 @@
 namespace submodel {
 namespace map {
 
+struct ModelTypePath {
+  static constexpr char Name[] = "name";
+  static constexpr char ModelType[] = "modelType";
+};
+
 template<ModelTypes modelType>
 class ModelType :
 	public virtual api::IModelType,
@@ -27,14 +32,14 @@
 ModelType<modelType>::ModelType()
 {
 	auto modelTypeMap = basyx::object::make_map();
-	modelTypeMap.insertKey("name", ModelTypes_::to_string(modelType));
-	this->map.insertKey("modelType", modelTypeMap);
+	modelTypeMap.insertKey(ModelTypePath::Name, ModelTypes_::to_string(modelType));
+	this->map.insertKey(ModelTypePath::ModelType, modelTypeMap);
 };
 
 template<ModelTypes modelType>
 ModelTypes ModelType<modelType>::GetModelType() const
 {
-	auto model_type = this->map.getProperty("modelType").getProperty("name").Get<std::string&>();
+	auto model_type = this->map.getProperty(ModelTypePath::ModelType).getProperty(ModelTypePath::Name).Get<std::string&>();
 	return ModelTypes_::from_string(model_type);
 };
 
@@ -42,4 +47,4 @@
 }
 }
 
-#endif /* BASYX_SUBMODEL_MAP_V2_COMMON_LANGSTRINGSET_H */
+#endif /* BASYX_SUBMODEL_MAP_V2_COMMON_MODELTYPE_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/common/SubModelContainer.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/common/SubModelContainer.h
new file mode 100644
index 0000000..1053159
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/common/SubModelContainer.h
@@ -0,0 +1,26 @@
+#ifndef BASYX_SUBMODEL_MAP_V2_COMMON_SUBMODELCONTAINER_H
+#define BASYX_SUBMODEL_MAP_V2_COMMON_SUBMODELCONTAINER_H
+
+#include <BaSyx/submodel/api_v2/ISubModel.h>
+#include <BaSyx/submodel/map_v2/common/ElementContainer.h>
+#include <BaSyx/vab/ElementMap.h>
+
+#include <unordered_map>
+#include <algorithm>
+
+namespace basyx {
+namespace submodel {
+namespace map {
+
+class SubModelContainer : public map::ElementContainer<api::ISubModel>
+{
+public:
+
+};
+
+
+}
+}
+}
+
+#endif /* BASYX_SUBMODEL_MAP_V2_COMMON_SUBMODELCONTAINER_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/constraint/Formula.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/constraint/Formula.h
index 5ce2085..efb431a 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/constraint/Formula.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/constraint/Formula.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_SUBMODEL_MAP_V2_QUALIFIER_FORMULA_H
-#define BASYX_SUBMODEL_MAP_V2_QUALIFIER_FORMULA_H
+#ifndef BASYX_SUBMODEL_MAP_V2_CONSTRAINT_FORMULA_H
+#define BASYX_SUBMODEL_MAP_V2_CONSTRAINT_FORMULA_H
 
 #include <BaSyx/submodel/api_v2/constraint/IFormula.h>
 #include <BaSyx/submodel/map_v2/common/ModelType.h>
@@ -17,6 +17,11 @@
 	public virtual vab::ElementMap
 {
 public:
+  struct Path {
+    static constexpr char Dependencies[] = "dependencies";
+  };
+
+public:
 	using vab::ElementMap::ElementMap;
 
 	Formula();
@@ -39,4 +44,4 @@
 }
 }
 
-#endif /* BASYX_SUBMODEL_API_V2_QUALIFIER_IFORMULA_H */
\ No newline at end of file
+#endif /* BASYX_SUBMODEL_MAP_V2_CONSTRAINT_FORMULA_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/constraint/Qualifier.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/constraint/Qualifier.h
index 69d6b76..b98998f 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/constraint/Qualifier.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/constraint/Qualifier.h
@@ -17,6 +17,16 @@
 	public ModelType<ModelTypes::Qualifier>,
 	public virtual vab::ElementMap
 {
+public:
+  struct Path {
+    static constexpr char ValueDataType[] = "valueDataType";
+    static constexpr char QualifierType[] = "qualifierType";
+    static constexpr char ValueType[] = "valueType";
+    static constexpr char SemanticId[] = "semanticId";
+    static constexpr char ValueId[] = "valueId";
+  };
+
+
 private:
 	Reference valueId;
 	Reference semanticId;
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/dataspecification/DataSpecification.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/dataspecification/DataSpecification.h
index b63072a..d0de685 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/dataspecification/DataSpecification.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/dataspecification/DataSpecification.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_MAP_V2_SDK_DATASPECIFICATION
-#define BASYX_MAP_V2_SDK_DATASPECIFICATION
+#ifndef BASYX_SUBMODEL_MAP_V2_DATASPECIFICATION_DATASPECIFICATION_H
+#define BASYX_SUBMODEL_MAP_V2_DATASPECIFICATION_DATASPECIFICATION_H
 
 #include <BaSyx/submodel/api_v2/dataspecification/IDataSpecification.h>
 #include <BaSyx/submodel/map_v2/dataspecification/DataSpecificationContent.h>
@@ -17,6 +17,11 @@
     public virtual Identifiable,
     public virtual vab::ElementMap
 {
+public:
+  struct Path {
+    static constexpr char DataSpecificationContent[] = "dataSpecificationContent";
+  };
+
 private:
   std::unique_ptr<DataSpecificationContent> content;
 public:
@@ -26,9 +31,10 @@
   api::IDataSpecificationContent & getContent() override;
 
   void setContent(std::unique_ptr<DataSpecificationContent> content);
+  virtual KeyElements getKeyElementType() const override { return KeyElements::Unknown; };
 };
 
 }
 }
 }
-#endif //BASYX_MAP_V2_SDK_DATASPECIFICATION_H
+#endif /* BASYX_SUBMODEL_MAP_V2_DATASPECIFICATION_DATASPECIFICATION_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/dataspecification/DataSpecificationContent.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/dataspecification/DataSpecificationContent.h
index cd64864..d87c8e2 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/dataspecification/DataSpecificationContent.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/dataspecification/DataSpecificationContent.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_MAP_V2_SDK_DATASPECIFICATIONCONTENT_H
-#define BASYX_MAP_V2_SDK_DATASPECIFICATIONCONTENT_H
+#ifndef BASYX_SUBMODEL_MAP_V2_DATASPECIFICATION_DATASPECIFICATIONCONTENT_H
+#define BASYX_SUBMODEL_MAP_V2_DATASPECIFICATION_DATASPECIFICATIONCONTENT_H
 
 #include <BaSyx/submodel/api_v2/dataspecification/IDataSpecificationContent.h>
 
@@ -17,4 +17,4 @@
 }
 }
 }
-#endif //BASYX_MAP_V2_SDK_DATASPECIFICATIONCONTENT_H
+#endif /* BASYX_SUBMODEL_MAP_V2_DATASPECIFICATION_DATASPECIFICATIONCONTENT_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/dataspecification/DataSpecificationIEC61360.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/dataspecification/DataSpecificationIEC61360.h
index 53860e2..fad7225 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/dataspecification/DataSpecificationIEC61360.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/dataspecification/DataSpecificationIEC61360.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_MAP_V2_SDK_DATASPECIFICATIONIEC61360_H
-#define BASYX_MAP_V2_SDK_DATASPECIFICATIONIEC61360_H
+#ifndef BASYX_SUBMODEL_MAP_V2_DATASPECIFICATION_DATASPECIFICATIONIEC61360_H
+#define BASYX_SUBMODEL_MAP_V2_DATASPECIFICATION_DATASPECIFICATIONIEC61360_H
 
 #include <BaSyx/submodel/api_v2/dataspecification/IDataSpecificationIEC61360.h>
 
@@ -76,4 +76,4 @@
 }
 }
 }
-#endif //BASYX_MAP_V2_SDK_DATASPECIFICATIONIEC61360_H
+#endif /* BASYX_SUBMODEL_MAP_V2_DATASPECIFICATION_DATASPECIFICATIONIEC61360_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/dataspecification/DataSpecificationPhysicalUnit.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/dataspecification/DataSpecificationPhysicalUnit.h
index c1107da..b91925b 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/dataspecification/DataSpecificationPhysicalUnit.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/dataspecification/DataSpecificationPhysicalUnit.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_MAP_V2_SDK_DATASPECIFICATIONPHYSICALUNIT_H_
-#define BASYX_MAP_V2_SDK_DATASPECIFICATIONPHYSICALUNIT_H_
+#ifndef BASYX_SUBMODEL_MAP_V2_DATASPECIFICATION_DATASPECIFICATIONPHYSICALUNIT_H
+#define BASYX_SUBMODEL_MAP_V2_DATASPECIFICATION_DATASPECIFICATIONPHYSICALUNIT_H
 
 #include <BaSyx/submodel/api_v2/dataspecification/IDataSpecificationPhysicalUnit.h>
 #include <BaSyx/submodel/map_v2/common/LangStringSet.h>
@@ -83,4 +83,4 @@
 }
 }
 
-#endif //BASYX_MAP_V2_SDK_DATASPECIFICATIONPHYSICALUNIT_H_
+#endif /* BASYX_SUBMODEL_MAP_V2_DATASPECIFICATION_DATASPECIFICATIONPHYSICALUNIT_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/dataspecification/ValueList.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/dataspecification/ValueList.h
index b4dbb6b..5342c51 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/dataspecification/ValueList.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/dataspecification/ValueList.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_C_SDK_VALUELIST_H
-#define BASYX_C_SDK_VALUELIST_H
+#ifndef BASYX_SUBMODEL_MAP_V2_DATASPECIFICATION_VALUELIST_H
+#define BASYX_SUBMODEL_MAP_V2_DATASPECIFICATION_VALUELIST_H
 
 #include <BaSyx/submodel/api_v2/dataspecification/IValueList.h>
 #include <BaSyx/vab/ElementMap.h>
@@ -13,6 +13,12 @@
   , public vab::ElementMap
 {
 public:
+  struct Path {
+    static constexpr char Value[] = "value";
+    static constexpr char ValueId[] = "valueId";
+  };
+
+public:
   ValueList();
   explicit ValueList(const std::vector<simple::ValueReferencePair> & list);
 
@@ -24,4 +30,4 @@
 }
 }
 
-#endif //BASYX_C_SDK_VALUELIST_H
+#endif /* BASYX_SUBMODEL_MAP_V2_DATASPECIFICATION_VALUELIST_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/parts/ConceptDescription.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/parts/ConceptDescription.h
index 590be73..873c5b2 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/parts/ConceptDescription.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/parts/ConceptDescription.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_MAP_V2_SDK_CONCEPTDESCRIPTION_H
-#define BASYX_MAP_V2_SDK_CONCEPTDESCRIPTION_H
+#ifndef BASYX_SUBMODEL_MAP_V2_PARTS_CONCEPTDESCRIPTION_H
+#define BASYX_SUBMODEL_MAP_V2_PARTS_CONCEPTDESCRIPTION_H
 
 #include <BaSyx/vab/ElementMap.h>
 #include <BaSyx/submodel/api_v2/parts/IConceptDescription.h>
@@ -40,9 +40,11 @@
   //not inherited
   void addIsCaseOf(std::unique_ptr<Reference> reference);
   void addEmbeddedDataSpecification(std::unique_ptr<DataSpecification> data_specification);
+
+  virtual KeyElements getKeyElementType() const override { return KeyElements::ConceptDescription; };
 };
 
 }
 }
 }
-#endif //BASYX_MAP_V2_SDK_CONCEPTDESCRIPTION_H
+#endif /* BASYX_SUBMODEL_MAP_V2_PARTS_CONCEPTDESCRIPTION_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/parts/ConceptDictionary.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/parts/ConceptDictionary.h
index 45e3655..d555dff 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/parts/ConceptDictionary.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/parts/ConceptDictionary.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_MAP_V2_SDK_CONCEPTDICTIONARY_H
-#define BASYX_MAP_V2_SDK_CONCEPTDICTIONARY_H
+#ifndef BASYX_SUBMODEL_MAP_V2_PARTS_CONCEPTDICTIONARY_H
+#define BASYX_SUBMODEL_MAP_V2_PARTS_CONCEPTDICTIONARY_H
 
 #include <BaSyx/submodel/api_v2/parts/IConceptDictionary.h>
 #include <BaSyx/submodel/map_v2/qualifier/Referable.h>
@@ -16,8 +16,14 @@
     , public virtual Referable
     , public virtual vab::ElementMap
 {
+public:
+  struct Path {
+    static constexpr char ConceptDescriptions[] = "conceptDescriptions";
+  };
+
 private:
   ElementContainer<api::IConceptDescription> concept_descriptions;
+
 public:
   ConceptDictionary(const std::string & idShort);
 
@@ -26,9 +32,12 @@
 
   // not inherited
   void addConceptDescription(std::unique_ptr<ConceptDescription> description);
+
+  virtual KeyElements getKeyElementType() const override { return KeyElements::ConceptDictionary; };
+
 };
 
 }
 }
 }
-#endif //BASYX_MAP_V2_SDK_CONCEPTDICTIONARY_H
+#endif /* BASYX_SUBMODEL_MAP_V2_PARTS_CONCEPTDICTIONARY_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/parts/View.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/parts/View.h
index a1936fd..208b197 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/parts/View.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/parts/View.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_MAP_V2_SDK_VIEW_H
-#define BASYX_MAP_V2_SDK_VIEW_H
+#ifndef BASYX_SUBMODEL_MAP_V2_PARTS_VIEW_H
+#define BASYX_SUBMODEL_MAP_V2_PARTS_VIEW_H
 
 #include <BaSyx/submodel/api_v2/parts/IView.h>
 
@@ -19,11 +19,18 @@
   , public virtual Referable
   , public virtual vab::ElementMap
 {
+public:
+  struct Path {
+    static constexpr char ContainedElements[] = "containedElements";
+    static constexpr char SemanticId[] = "semanticId";
+  };
+
 private:
   ElementContainer<IReferable> contained_elements;
   Reference semanticId;
 public:
-  View(const std::string & idShort, const Referable * parent = nullptr);
+  View(const std::string & idShort, Referable * parent = nullptr);
+  virtual ~View() = default;
 
   //inherited via api::IView
   const api::IElementContainer<IReferable> & getContainedElements() const override;
@@ -34,9 +41,11 @@
   //inherited via IHasSemantics
   const api::IReference & getSemanticId() const override;
   void setSemanticId(const api::IReference & reference) override;
+
+  virtual KeyElements getKeyElementType() const override { return KeyElements::View; };
 };
 
 }
 }
 }
-#endif //BASYX_MAP_V2_SDK_VIEW_H
+#endif /* BASYX_SUBMODEL_MAP_V2_PARTS_VIEW_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/qualifier/AdministrativeInformation.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/qualifier/AdministrativeInformation.h
new file mode 100644
index 0000000..c3aa385
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/qualifier/AdministrativeInformation.h
@@ -0,0 +1,41 @@
+#ifndef BASYX_SUBMODEL_MAP_V2_QUALIFIER_ADMINISTRATIVEINFORMATION_H
+#define BASYX_SUBMODEL_MAP_V2_QUALIFIER_ADMINISTRATIVEINFORMATION_H
+
+#include <BaSyx/submodel/api_v2/qualifier/IAdministrativeInformation.h>
+
+#include <BaSyx/submodel/map_v2/qualifier/HasDataSpecification.h>
+#include <BaSyx/vab/ElementMap.h>
+
+namespace basyx {
+namespace submodel {
+namespace map {
+
+class AdministrativeInformation
+  : public virtual api::IAdministrativeInformation
+  , public HasDataSpecification
+  , public virtual vab::ElementMap
+{
+public:
+  struct Path {
+    static constexpr char Version[] = "version";
+    static constexpr char Revision[] = "revision";
+  };
+
+public:
+  AdministrativeInformation();
+  AdministrativeInformation(const std::string & version, const std::string & revision);
+
+  void setVersion(const std::string & version) override;
+  void setRevision(const std::string & revision) override;
+
+  bool hasVersion() const override;
+  bool hasRevision() const override;
+
+  const std::string * const getVersion() const override;
+  const std::string * const getRevision() const override;
+};
+
+}
+}
+}
+#endif /* BASYX_SUBMODEL_MAP_V2_QUALIFIER_ADMINISTRATIVEINFORMATION_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/qualifier/HasDataSpecification.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/qualifier/HasDataSpecification.h
index fd88eeb..a631c4e 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/qualifier/HasDataSpecification.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/qualifier/HasDataSpecification.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_SUBMODEL_METAMODEL_MAPv2_QUALIFIER_HASDATASPECIFICATION_H_
-#define BASYX_SUBMODEL_METAMODEL_MAPv2_QUALIFIER_HASDATASPECIFICATION_H_
+#ifndef BASYX_SUBMODEL_MAP_V2_QUALIFIER_HASDATASPECIFICATION_H
+#define BASYX_SUBMODEL_MAP_V2_QUALIFIER_HASDATASPECIFICATION_H
 
 #include <BaSyx/submodel/api_v2/qualifier/IHasDataSpecification.h>
 
@@ -13,6 +13,11 @@
 	public virtual api::IHasDataSpecification,
 	public virtual vab::ElementMap
 {
+public:
+  struct Path {
+    static constexpr char DataSpecification[] = "dataSpecification";
+  };
+
 private:
 	basyx::object::object_list_t dataSpecification;
 public:
@@ -28,4 +33,4 @@
 }
 }
 
-#endif
\ No newline at end of file
+#endif /* BASYX_SUBMODEL_MAP_V2_QUALIFIER_HASDATASPECIFICATION_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/qualifier/Identifiable.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/qualifier/Identifiable.h
index 87ecc5d..9fe83cb 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/qualifier/Identifiable.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/qualifier/Identifiable.h
@@ -3,7 +3,7 @@
 
 #include <BaSyx/submodel/api_v2/qualifier/IIdentifiable.h>
 #include <BaSyx/submodel/map_v2/qualifier/Referable.h>
-#include <BaSyx/submodel/simple/qualifier/AdministrativeInformation.h>
+#include <BaSyx/submodel/map_v2/qualifier/AdministrativeInformation.h>
 
 namespace basyx {
 namespace submodel {
@@ -13,26 +13,30 @@
 	public virtual api::IIdentifiable,
 	public Referable
 {
+public:
+  struct Path {
+    static constexpr char IdType[] = "idType";
+    static constexpr char Id[] = "id";
+    static constexpr char AdministrativeInformation[] = "administrativeInformation";
+    static constexpr char Identifier[] = "identification";
+  };
 private:
-//	Referable referable;
-	simple::AdministrativeInformation administrativeInformation;
+	map::AdministrativeInformation administrativeInformation;
 public:
 	virtual ~Identifiable() = default;
 
 	// Constructors
 	Identifiable(const std::string & idShort, const simple::Identifier & identifier);
 
-	//// Member-access
-	//inline const Referable & getReferable() const noexcept { return this->referable; };
-	//inline Referable & getReferable() noexcept { return this->referable; };
-
-	bool hasAdministrativeInformation() const noexcept;
+	bool hasAdministrativeInformation() const noexcept override;
 
 	// Inherited via IIdentifiable
-	virtual const simple::AdministrativeInformation & getAdministrativeInformation() const override;
-	virtual simple::AdministrativeInformation & getAdministrativeInformation() override;
+	const api::IAdministrativeInformation & getAdministrativeInformation() const override;
+	api::IAdministrativeInformation & getAdministrativeInformation() override;
 
 	virtual simple::Identifier getIdentification() const override;
+
+    void setAdministrativeInformation(const AdministrativeInformation & administrativeInformation);
 };
 
 }
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/qualifier/Qualifiable.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/qualifier/Qualifiable.h
index f8e74e1..8ff2fbb 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/qualifier/Qualifiable.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/qualifier/Qualifiable.h
@@ -2,7 +2,7 @@
 #define BASYX_SUBMODEL_MAP_V2_QUALIFIER_QUALIFIABLE_H
 
 #include <BaSyx/submodel/api_v2/qualifier/IQualifiable.h>
-
+#include <BaSyx/submodel/simple/constraint/Qualifier.h>
 #include <BaSyx/vab/ElementMap.h>
 
 namespace basyx {
@@ -15,6 +15,10 @@
 	public virtual vab::ElementMap
 {
 public:
+  struct Path {
+    static constexpr char Qualifier[] = "qualifier";
+  };
+public:
 	Qualifiable() = default;
 	Qualifiable(const std::vector<simple::Formula> & formulas, const std::vector<simple::Qualifier> & qualifiers);
 
@@ -37,4 +41,4 @@
 }
 }
 
-#endif /* BASYX_SUBMODEL_MAP_V2_QUALIFIER_IQUALIFIABLE_H */
\ No newline at end of file
+#endif /* BASYX_SUBMODEL_MAP_V2_QUALIFIER_QUALIFIABLE_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/qualifier/Referable.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/qualifier/Referable.h
index 9ca9295..8052f9b 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/qualifier/Referable.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/qualifier/Referable.h
@@ -24,12 +24,12 @@
 	};
 private:
 	map::LangStringSet description;
-	const IReferable * const parent = nullptr;
+	IReferable * parent = nullptr;
 public:
 	virtual ~Referable() = default;
 
 	// Constructors
-	Referable(const std::string & idShort, const Referable * parent = nullptr);
+	Referable(const std::string & idShort, Referable * parent = nullptr);
 	//Referable(const IReferable & other);
 
 	// Inherited via IReferable
@@ -38,15 +38,19 @@
 	virtual LangStringSet & getDescription() override;
 	virtual const LangStringSet & getDescription() const override;
 
-	virtual const IReferable * const getParent() const override;
+	virtual void setParent(IReferable * parent) override;
+	virtual IReferable * getParent() const override;
 
-	// not inherited
 	void setIdShort(const std::string & shortID);
 	void setCategory(const std::string & category) override;
 
 	bool hasParent() const noexcept;
 	bool hasDescription() const noexcept;
 	bool hasCategory() const noexcept;
+
+	virtual KeyElements getKeyElementType() const override { return KeyElements::Unknown; };
+	virtual simple::Reference getReference() const override;
+	virtual simple::Key getKey(bool local = true) const override;
 };
 
 
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/reference/Reference.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/reference/Reference.h
index efada7a..19e9adf 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/reference/Reference.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/reference/Reference.h
@@ -15,9 +15,13 @@
 	public virtual vab::ElementMap
 {
 public:
-	struct Path	{
-		static constexpr char Keys[] = "keys";
-	};
+  struct Path {
+    static constexpr char IdType[] = "idType";
+    static constexpr char Type[] = "type";
+    static constexpr char Value[] = "value";
+    static constexpr char Local[] = "local";
+    static constexpr char Keys[] = "keys";
+  };
 public:
 	Reference();
 public:
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/submodelelement/SubmodelElement.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/submodelelement/SubmodelElement.h
index 16e0f08..94d5903 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/submodelelement/SubmodelElement.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/submodelelement/SubmodelElement.h
@@ -3,34 +3,44 @@
 
 #include <BaSyx/submodel/api_v2/submodelelement/ISubmodelElement.h>
 
+#include <BaSyx/submodel/map_v2/common/ModelType.h>
 #include <BaSyx/submodel/map_v2/qualifier/HasDataSpecification.h>
+#include <BaSyx/submodel/map_v2/qualifier/Qualifiable.h>
 #include <BaSyx/submodel/map_v2/qualifier/Referable.h>
 #include <BaSyx/submodel/map_v2/reference/Reference.h>
 
-
 namespace basyx {
 namespace submodel {
 namespace map {
 
-class SubmodelElement : 
-	public virtual api::ISubmodelElement,
-	public virtual vab::ElementMap,
-	public Referable,
-	public HasDataSpecification
+class SubmodelElement
+  :	public virtual api::ISubmodelElement
+  , public virtual vab::ElementMap
+  , public virtual Qualifiable
+  , public Referable
+  , public HasDataSpecification
 {
-private:
-	Reference semanticId;
 public:
-	SubmodelElement(const std::string & idShort, ModelingKind kind = ModelingKind::Instance);
+  struct Path {
+    static constexpr char Kind[] = "kind";
+    static constexpr char SemanticId[] = "semanticId";
+  };
+private:
+    Reference semanticId;
 
-	virtual ~SubmodelElement() = default;
+public:
+    SubmodelElement(const std::string& idShort, ModelingKind kind = ModelingKind::Instance);
 
-	// Inherited via IHasDataSemantics
-	virtual const api::IReference & getSemanticId() const override;
-	void setSemanticId(const api::IReference & reference);
+    virtual ~SubmodelElement() = default;
 
-	// Inherited via IHasKind
-	virtual ModelingKind getKind() const override;
+    // Inherited via IHasDataSemantics
+    virtual const api::IReference& getSemanticId() const override;
+    void setSemanticId(const api::IReference& reference) override;
+
+    // Inherited via IHasKind
+    virtual ModelingKind getKind() const override;
+
+    virtual KeyElements getKeyElementType() const override { return KeyElements::SubmodelElement; };
 };
 
 }
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/submodelelement/SubmodelElementCollection.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/submodelelement/SubmodelElementCollection.h
index 02d7ce3..061326f 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/submodelelement/SubmodelElementCollection.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/submodelelement/SubmodelElementCollection.h
@@ -33,6 +33,8 @@
 
 	virtual bool isOrdered() const override;
 	virtual bool isAllowDuplicates() const override;
+
+	virtual KeyElements getKeyElementType() const override { return KeyElements::SubmodelElementCollection; };
 };
 
 }
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/submodelelement/SubmodelElementFactory.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/submodelelement/SubmodelElementFactory.h
index 0438908..cf34721 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/submodelelement/SubmodelElementFactory.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/submodelelement/SubmodelElementFactory.h
@@ -11,6 +11,10 @@
 
 class SubmodelElementFactory
 {
+public:
+  struct Path {
+    static constexpr char Value[] = "value";
+  };
 private:
 	static std::unique_ptr<api::ISubmodelElement> CreateProperty(const vab::ElementMap & elementMap);
 public:
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/submodelelement/operation/Operation.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/submodelelement/operation/Operation.h
index 19d8636..96efd50 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/submodelelement/operation/Operation.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/submodelelement/operation/Operation.h
@@ -15,6 +15,13 @@
 	public SubmodelElement,
 	public ModelType<ModelTypes::Operation>
 {
+public:
+  struct Path {
+    static constexpr char Invokable[] = "invokable";
+    static constexpr char InputVariable[] = "inputVariable";
+    static constexpr char OutputVariable[] = "outputVariable";
+    static constexpr char InoutputVariable[] = "inoutputVariable";
+  };
 private:
 	ElementContainer<ISubmodelElement> inputVariables;
 	ElementContainer<ISubmodelElement> outputVariables;
@@ -30,6 +37,8 @@
 	virtual api::IElementContainer<ISubmodelElement> & getOutputVariables() override;
 	virtual api::IElementContainer<ISubmodelElement> & getInOutputVariables() override;
 	virtual basyx::object invoke(basyx::object args) override;
+
+	virtual KeyElements getKeyElementType() const override { return KeyElements::Operation; };
 };
 
 }
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/submodelelement/operation/OperationVariable.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/submodelelement/operation/OperationVariable.h
index d835e3b..b688d42 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/submodelelement/operation/OperationVariable.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/submodelelement/operation/OperationVariable.h
@@ -8,6 +8,12 @@
 namespace submodel {
 namespace map {
 
+struct OperationVariablePath {
+  static constexpr char Value[] = "value";
+};
+
+constexpr char OperationVariablePath::Value[];
+
 template<typename T>
 class OperationVariable : 
 	public SubmodelElement, 
@@ -21,7 +27,7 @@
 		: SubmodelElement(idShort, ModelingKind::Template)
 		, value(std::move(value))
 	{
-		this->map.insertKey("value", this->value->getMap());
+		this->map.insertKey(OperationVariablePath::Value, this->value->getMap());
 	};
 
 	OperationVariable(const OperationVariable & other) = default;
@@ -37,6 +43,8 @@
 	{
 		return *this->value;
 	};
+
+	virtual inline KeyElements getKeyElementType() const override { return KeyElements::OperationVariable; };
 };
 
 
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/submodelelement/property/MultiLanguageProperty.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/submodelelement/property/MultiLanguageProperty.h
index 8ecc6f8..d108f75 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/submodelelement/property/MultiLanguageProperty.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/submodelelement/property/MultiLanguageProperty.h
@@ -17,6 +17,12 @@
 	public SubmodelElement,
 	public ModelType<ModelTypes::MultiLanguageProperty>
 {
+public:
+  struct Path {
+    static constexpr char Value[] = "value";
+    static constexpr char ValueId[] = "valueId";
+    static constexpr char Kind[] = "kind";
+  };
 private:
 	LangStringSet value;
 	Reference valueId;
@@ -28,6 +34,8 @@
 
 	virtual const api::IReference * const getValueId() const override;
 	virtual void setValueId(const api::IReference & valueId) override;
+
+	virtual KeyElements getKeyElementType() const override { return KeyElements::MultiLanguageProperty; };
 };
 
 
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/submodelelement/property/Property.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/submodelelement/property/Property.h
index debb500..082733f 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/submodelelement/property/Property.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/submodelelement/property/Property.h
@@ -4,6 +4,8 @@
 #include <BaSyx/submodel/api_v2/submodelelement/property/IProperty.h>
 #include <BaSyx/submodel/map_v2/submodelelement/SubmodelElement.h>
 #include <BaSyx/submodel/map_v2/common/ModelType.h>
+#include <BaSyx/submodel/map_v2/qualifier/Qualifiable.h>
+#include <BaSyx/submodel/api_v2/submodelelement/property/XSDAnySimpleType.h>
 
 #include <BaSyx/shared/object.h>
 
@@ -11,66 +13,94 @@
 namespace submodel {
 namespace map {
 
+struct PropertyPath {
+  static constexpr char Value[] = "value";
+  static constexpr char ValueType[] = "valueType";
+  static constexpr char ValueId[] = "valueId";
+};
+
 template<typename T>
 class Property
-  : public virtual api::IProperty
-  , public virtual SubmodelElement
-  , public virtual vab::ElementMap
-  , public ModelType<ModelTypes::Property>
+    : public virtual api::IProperty
+        , public virtual SubmodelElement
+        , public virtual vab::ElementMap
+        , public virtual Qualifiable
+        , public ModelType<ModelTypes::Property>
 {
+private:
+  std::unique_ptr<Reference> valueId;
+
 public:
-	Property(const std::string & idShort)
-		: SubmodelElement(idShort, ModelingKind::Instance)
-	{
-	};
+  Property(const std::string & idShort)
+      : SubmodelElement(idShort, ModelingKind::Instance)
+  {
+    this->setValueType(xsd_types::xsd_type<T>::getDataTypeDef());
+  };
 
-	Property(const vab::ElementMap & elementMap)
-		: vab::ElementMap(elementMap.getMap())
-		, SubmodelElement(elementMap.getMap().getProperty(Referable::Path::IdShort).GetStringContent(), ModelingKind::Instance)
-	{
-	};
+  Property(const vab::ElementMap & elementMap)
+      : vab::ElementMap(elementMap.getMap())
+      , SubmodelElement(elementMap.getMap().getProperty(Referable::Path::IdShort).GetStringContent(), ModelingKind::Instance)
+  {
+  };
 
-	virtual ~Property() = default;
+  virtual ~Property() = default;
 
-	void setValue(const T & t)
-	{
-		this->map.insertKey("value", t);
-	}
+  void setValue(const T & t)
+  {
+    this->map.insertKey(PropertyPath::Value, xsd_types::xsd_type<T>::getXSDRepresentation(t));
+  }
 
-	const T & getValue() const
-	{
-		return this->map.getProperty("value").template Get<T&>();
-	}
+  const T getValue() const
+  {
+    return xsd_types::xsd_type<T>::fromXSDRepresentation(this->map.getProperty(PropertyPath::Value));
+  }
 
-	virtual const std::string & getValueType() const override
-	{
-		return this->map.getProperty("valueType").template Get<std::string&>();
-	}
+  virtual const std::string & getValueType() const override
+  {
+    return this->map.getProperty(PropertyPath::ValueType).template Get<std::string&>();
+  }
 
-	virtual void setValueType(const std::string & valueType) override
-	{
-		this->map.insertKey("valueType", valueType);
-	}
+  virtual void setValueType(const std::string & valueType) override
+  {
+    this->map.insertKey(PropertyPath::ValueType, valueType);
+  }
 
-	virtual void setObject(basyx::object & object) override
-	{
-		if (object.InstanceOf<T>())
-			this->map.insertKey("value", object);
-	}
+  virtual void setObject(basyx::object & object) override
+  {
+    // store only if valuetype is defined
+    if (object.hasProperty(PropertyPath::ValueType))
+      this->map = object;
 
-	virtual basyx::object getObject() override
-	{
-		return this->map.getProperty("value");
-	}
+    // or if it's a primitive type, not null or object
+    if (object.GetObjectType() == type::objectType::Primitive)
+    {
+      if (object.GetValueType() != type::valueType::Null and object.GetValueType() != type::valueType::Object)
+        this->map.insertKey(PropertyPath::Value, object);
+        this->map.insertKey(PropertyPath::ValueType, xsd_types::getPrimitiveXSDType(object.GetValueType()));
+    }
+  }
 
-	virtual const Reference * const getValueId() const override
-	{
-		return nullptr;
-	}
+  virtual basyx::object getObject() override
+  {
+    return this->map.getProperty(PropertyPath::Value);
+  }
 
-	virtual void setValueId(const api::IReference & valueId) override
-	{
-	}
+  virtual const Reference * const getValueId() const override
+  {
+    if (&this->valueId)
+    {
+      return this->valueId.get();
+    }
+    return nullptr;
+  }
+
+  virtual void setValueId(const api::IReference & valueId) override
+  {
+    this->valueId = util::make_unique<Reference>(valueId);
+    this->map.insertKey(PropertyPath::ValueId, this->valueId->getMap());
+  }
+
+  virtual KeyElements getKeyElementType() const override { return KeyElements::Property; };
 };
 
 }
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/submodelelement/property/ReferenceElement.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/submodelelement/property/ReferenceElement.h
index 8fdaa6c..fa94b34 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/submodelelement/property/ReferenceElement.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/submodelelement/property/ReferenceElement.h
@@ -2,29 +2,33 @@
 #define BASYX_SUBMODEL_MAP_V2_SUBMODELELEMENT_PROPERTY_REFERENCEELEMENT_H
 
 #include <BaSyx/submodel/api_v2/submodelelement/property/IReferenceElement.h>
-#include <BaSyx/submodel/map_v2/submodelelement/SubmodelElement.h>
-#include <BaSyx/submodel/map_v2/reference/Reference.h>
 #include <BaSyx/submodel/map_v2/common/ModelType.h>
-
+#include <BaSyx/submodel/map_v2/reference/Reference.h>
+#include <BaSyx/submodel/map_v2/submodelelement/SubmodelElement.h>
 
 namespace basyx {
 namespace submodel {
 namespace map {
 
-
-class ReferenceElement : 
-	public api::IReferenceElement,
-	public SubmodelElement,
-	public ModelType<ModelTypes::ReferenceElement>
+class ReferenceElement : public api::IReferenceElement,
+                         public SubmodelElement,
+                         public ModelType<ModelTypes::ReferenceElement> 
 {
-private:
-	Reference value;
 public:
-	ReferenceElement(const std::string & idShort, ModelingKind kind = ModelingKind::Instance);
-	virtual ~ReferenceElement() = default;
+  struct Path {
+    static constexpr char Value[] = "value";
+    static constexpr char Kind[] = "kind";
+  };
+private:
+    Reference value;
+public:
+    ReferenceElement(const std::string& idShort, ModelingKind kind = ModelingKind::Instance);
+    virtual ~ReferenceElement() = default;
 
-	virtual const api::IReference * const getValue() const = 0;
-	virtual void setValue(const api::IReference & value) = 0;
+    virtual const api::IReference* const getValue() const override = 0;
+    virtual void setValue(const api::IReference& value) override = 0;
+
+    virtual KeyElements getKeyElementType() const override { return KeyElements::ReferenceElement; };
 };
 
 }
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/SubModel.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/SubModel.h
index 78f7904..88e2cee 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/SubModel.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/SubModel.h
@@ -47,8 +47,10 @@
 	virtual void setCategory(const std::string & category) override;
 	virtual simple::LangStringSet & getDescription() override;
 	virtual const simple::LangStringSet & getDescription() const override;
-	virtual const IReferable * const getParent() const override;
-
+	
+	virtual IReferable * getParent() const override;
+	virtual void setParent(IReferable * parent) override;
+	
 	// Inherited via IIdentifiable
 	virtual const AdministrativeInformation & getAdministrativeInformation() const override;
 	virtual AdministrativeInformation & getAdministrativeInformation() override;
@@ -71,6 +73,10 @@
 
 	virtual std::vector<simple::Formula> getFormulas() const override;
 	virtual std::vector<simple::Qualifier> getQualifiers() const override;
+
+	virtual KeyElements getKeyElementType() const override { return KeyElements::Submodel; };
+	virtual simple::Reference getReference() const override;
+	virtual simple::Key getKey(bool local = true) const override;
 };
 
 
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/aas/Asset.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/aas/Asset.h
index fc0cd26..39b1a3d 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/aas/Asset.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/aas/Asset.h
@@ -22,7 +22,7 @@
 	Asset(const std::string & idShort, const Identifier & identifier, AssetKind kind = AssetKind::Instance);
 	virtual ~Asset() = default;
 
-	virtual AssetKind getKind();
+	virtual AssetKind getKind() override;
 
 	virtual Reference * const getAssetIdentificationModel() override;
 	virtual void setAssetIdentificationModel(const api::IReference & assetIdentificationModelRef) override;
@@ -37,7 +37,9 @@
 	virtual void setCategory(const std::string & category) override;
 	virtual simple::LangStringSet & getDescription() override;
 	virtual const simple::LangStringSet & getDescription() const override;
-	virtual const IReferable * const getParent() const override;
+	virtual void setParent(api::IReferable * parent) override;
+	virtual IReferable * getParent() const override;
+	virtual simple::Reference getReference() const override;
 
 	// Inherited via IIdentifiable
 	virtual const AdministrativeInformation & getAdministrativeInformation() const override;
@@ -45,13 +47,15 @@
 
 	virtual Identifier getIdentification() const override;
 
-	virtual bool hasAdministrativeInformation() const;
+	virtual bool hasAdministrativeInformation() const override;
 
 	// Inherited via IHasDataSpecification
 	virtual void addDataSpecification(const Reference & reference) override;
 	virtual const std::vector<Reference> getDataSpecificationReference() const override;
 
 	virtual inline ModelTypes GetModelType() const override { return ModelTypes::Asset; };
+	virtual KeyElements getKeyElementType() const override { return KeyElements::Asset; };
+	virtual Key getKey(bool local = true) const override;
 };
 
 }
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/aas/AssetAdministrationShell.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/aas/AssetAdministrationShell.h
index 634d414..be14ce2 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/aas/AssetAdministrationShell.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/aas/AssetAdministrationShell.h
@@ -16,6 +16,8 @@
 
 class AssetAdministrationShell : public api::IAssetAdministrationShell
 {
+public:
+	using asset_t = basyx::submodel::simple::Asset;
 private:
 	Identifiable identifiable;
 	HasDataSpecification dataSpecification;
@@ -43,19 +45,26 @@
 	virtual void setCategory(const std::string & category) override;
 	virtual simple::LangStringSet & getDescription() override;
 	virtual const simple::LangStringSet & getDescription() const override;
-	virtual const IReferable * const getParent() const override;
+	virtual void setParent(api::IReferable * parent) override;
+	virtual IReferable * getParent() const override;
+	virtual simple::Reference getReference() const override;
 
 	// Inherited via IIdentifiable
-	virtual const AdministrativeInformation & getAdministrativeInformation() const override;
-	virtual AdministrativeInformation & getAdministrativeInformation() override;
+	virtual const api::IAdministrativeInformation & getAdministrativeInformation() const override;
+	virtual api::IAdministrativeInformation & getAdministrativeInformation() override;
 
 	virtual Identifier getIdentification() const override;
 
-	virtual bool hasAdministrativeInformation() const;
+	virtual bool hasAdministrativeInformation() const override;
 
 	// Inherited via IHasDataSpecification
 	virtual void addDataSpecification(const Reference & reference) override;
 	virtual const std::vector<Reference> getDataSpecificationReference() const override;
+
+	// Inherited via IModelType
+	virtual ModelTypes GetModelType() const override;
+	virtual KeyElements getKeyElementType() const override { return KeyElements::AssetAdministrationShell; };
+	virtual Key getKey(bool local = true) const override;
 };
 
 }
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/ElementContainer.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/ElementContainer.h
index 5b22928..6f45a4a 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/ElementContainer.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/ElementContainer.h
@@ -17,12 +17,15 @@
     using container_t = std::vector<elementPtr_t>;
 private:
     container_t container;
+	api::IReferable * parent;
 public:
-	ElementContainer() = default;
+	ElementContainer(api::IReferable * parent = nullptr) : parent(parent) {};
 	virtual ~ElementContainer() = default;
 public:
 	// Inherited via IElementContainer
 	virtual std::size_t size() const override;
+	virtual api::IReferable * getParent() const override;
+
 	virtual IElementType * const getElement(const std::string & idShort) const override;
 	virtual IElementType * const getElement(std::size_t n) const override;
 	virtual void addElement(elementPtr_t element) override;
@@ -45,6 +48,12 @@
 };
 
 template<typename IElementType>
+api::IReferable * ElementContainer<IElementType>::getParent() const
+{
+	return this->parent;
+};
+
+template<typename IElementType>
 IElementType * const ElementContainer<IElementType>::getElement(const std::string & idShort) const
 {
 	auto ret = std::find_if(container.begin(), container.end(),
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/LangStringSet.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/LangStringSet.h
index b46249d..d9ff7d1 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/LangStringSet.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/LangStringSet.h
@@ -22,16 +22,16 @@
 	LangStringSet();
 	LangStringSet(const std::string & languageCode, const std::string & langString);
 	LangStringSet(std::initializer_list<langStringMap_t::value_type>);
-  LangStringSet(const api::ILangStringSet & other);
+	LangStringSet(const api::ILangStringSet & other);
 	virtual ~LangStringSet() = default;
 
 	langCodeSet_t getLanguageCodes() const override;
 
-  const std::string & get(const std::string & languageCode) const override;
-  void add(const std::string & languageCode, const std::string & langString) override;
+	const std::string & get(const std::string & languageCode) const override;
+	void add(const std::string & languageCode, const std::string & langString) override;
 	bool empty() const noexcept override;
 
-  friend bool api::operator==(const api::ILangStringSet & left, const api::ILangStringSet & right);
+	friend bool api::operator==(const api::ILangStringSet & left, const api::ILangStringSet & right);
 };
 
 }
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/xsd_types/AnyURI.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/xsd_types/AnyURI.h
new file mode 100644
index 0000000..65e225a
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/xsd_types/AnyURI.h
@@ -0,0 +1,25 @@
+#ifndef BASYX_SIMPLE_SDK_ANYURI_H
+#define BASYX_SIMPLE_SDK_ANYURI_H
+
+#include <BaSyx/vab/ElementMap.h>
+
+namespace basyx {
+namespace submodel {
+namespace simple {
+
+class AnyURI
+{
+private:
+  std::string uri;
+
+public:
+  AnyURI(const std::string & uri);
+
+  const std::string & getUri() const;
+  void setURI(const std::string & uri);
+};
+
+}
+}
+}
+#endif //BASYX_MAP_V2_SDK_ANYURI_H
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/xsd_types/Date.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/xsd_types/Date.h
new file mode 100644
index 0000000..b746364
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/xsd_types/Date.h
@@ -0,0 +1,25 @@
+#ifndef BASYX_SIMPLE_SDK_DATE_H
+#define BASYX_SIMPLE_SDK_DATE_H
+
+#include <ctime>
+
+namespace basyx {
+namespace submodel {
+namespace simple {
+
+class Date
+{
+private:
+  tm date;
+
+public:
+  Date(const tm &);
+
+  const tm & getDate() const;
+  void setDate(const tm &);
+};
+
+}
+}
+}
+#endif /* BASYX_SIMPLE_SDK_DATE_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/xsd_types/DateTime.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/xsd_types/DateTime.h
new file mode 100644
index 0000000..eaa665c
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/xsd_types/DateTime.h
@@ -0,0 +1,25 @@
+#ifndef BASYX_SIMPLE_SDK_DATETIME_H
+#define BASYX_SIMPLE_SDK_DATETIME_H
+
+#include <ctime>
+
+namespace basyx {
+namespace submodel {
+namespace simple {
+
+class DateTime
+{
+private:
+  tm time;
+
+public:
+  DateTime(const tm &);
+
+  const tm & getTime() const;
+  void setTime(const tm & time);
+};
+
+}
+}
+}
+#endif //BASYX_MAP_V2_SDK_DATETIME_H
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/xsd_types/DayTimeDuration.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/xsd_types/DayTimeDuration.h
new file mode 100644
index 0000000..03701b0
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/xsd_types/DayTimeDuration.h
@@ -0,0 +1,24 @@
+#ifndef BASYX_SIMPLE_SDK_DAYTIMEDURATION_H
+#define BASYX_SIMPLE_SDK_DAYTIMEDURATION_H
+
+#include <chrono>
+
+namespace basyx {
+namespace submodel {
+namespace simple {
+
+class DayTimeDuration
+{
+private:
+  std::chrono::duration<long> duration_in_sec;
+public:
+  DayTimeDuration(const std::chrono::duration<long> &);
+
+  const std::chrono::duration<long> & getDuration() const;
+  void setDuration(const std::chrono::duration<long> &);
+};
+
+}
+}
+}
+#endif /* BASYX_SIMPLE_SDK_DAYTIMEDURATION_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/xsd_types/GDay.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/xsd_types/GDay.h
new file mode 100644
index 0000000..099aba1
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/xsd_types/GDay.h
@@ -0,0 +1,29 @@
+#ifndef BASYX_SIMPLE_SDK_GDAY_H
+#define BASYX_SIMPLE_SDK_GDAY_H
+
+#include <BaSyx/submodel/simple/common/xsd_types/Timezone.h>
+
+namespace basyx {
+namespace submodel {
+namespace simple {
+
+class GDay
+{
+private:
+uint8_t day;
+  Timezone timezone;
+
+public:
+  GDay(uint8_t day, const Timezone & timezone = "Z");
+
+  uint8_t getDay() const;
+  void setDay(uint8_t day);
+
+  const Timezone & getTimezone() const;
+  void setTimezone(const Timezone &timezone);
+};
+
+}
+}
+}
+#endif /* BASYX_SIMPLE_SDK_GDAY_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/xsd_types/GMonth.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/xsd_types/GMonth.h
new file mode 100644
index 0000000..8010d78
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/xsd_types/GMonth.h
@@ -0,0 +1,29 @@
+#ifndef BASYX_SIMPLE_SDK_GMONTH_H
+#define BASYX_SIMPLE_SDK_GMONTH_H
+
+#include <BaSyx/submodel/simple/common/xsd_types/Timezone.h>
+
+namespace basyx {
+namespace submodel {
+namespace simple {
+
+class GMonth
+{
+private:
+  uint8_t month;
+  Timezone timezone;
+
+public:
+  GMonth(uint8_t month, const Timezone & timezone = "Z");
+
+  uint8_t getMonth() const;
+  void setMonth(uint8_t month);
+
+  const Timezone & getTimezone() const;
+  void setTimezone(const Timezone &timezone);
+};
+
+}
+}
+}
+#endif /* BASYX_SIMPLE_SDK_GMONTH_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/xsd_types/GMonthDay.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/xsd_types/GMonthDay.h
new file mode 100644
index 0000000..23c597b
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/xsd_types/GMonthDay.h
@@ -0,0 +1,35 @@
+#ifndef BASYX_SIMPLE_SDK_GMONTHDAY_H
+#define BASYX_SIMPLE_SDK_GMONTHDAY_H
+
+#include "Timezone.h"
+
+namespace basyx {
+namespace submodel {
+namespace simple {
+
+class GMonthDay
+{
+private:
+  uint8_t month, day;
+  Timezone timezone;
+
+  const uint8_t month_days[12] = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
+
+public:
+  GMonthDay(uint8_t month, uint8_t day, const Timezone & timezone = "Z");
+
+  uint8_t getMonth() const;
+  void setMonth(uint8_t month);
+
+  uint8_t getDay() const;
+  void setDay(uint8_t day);
+
+
+  const Timezone & getTimezone() const;
+  void setTimezone(const Timezone &timezone);
+};
+
+}
+}
+}
+#endif /* BASYX_SIMPLE_SDK_GMONTHDAY_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/xsd_types/GYear.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/xsd_types/GYear.h
new file mode 100644
index 0000000..a3f654f
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/xsd_types/GYear.h
@@ -0,0 +1,31 @@
+#ifndef BASYX_SIMPLE_SDK_GYEAR_H
+#define BASYX_SIMPLE_SDK_GYEAR_H
+
+#include <BaSyx/submodel/simple/common/xsd_types/Timezone.h>
+
+namespace basyx {
+namespace submodel {
+namespace simple {
+
+class GYear
+{
+private:
+  int year;
+  Timezone timezone;
+
+public:
+  GYear(int year, const Timezone & timezone = "Z");
+
+  int getYear() const;
+  void setYear(int year);
+
+  const Timezone & getTimezone() const;
+  void setTimezone(const Timezone &timezone);
+
+
+};
+
+}
+}
+}
+#endif /* BASYX_SIMPLE_SDK_GYEAR_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/xsd_types/GYearMonth.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/xsd_types/GYearMonth.h
new file mode 100644
index 0000000..27ad161
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/xsd_types/GYearMonth.h
@@ -0,0 +1,33 @@
+#ifndef BASYX_SIMPLE_SDK_GYEARMONTH_H
+#define BASYX_SIMPLE_SDK_GYEARMONTH_H
+
+#include "Timezone.h"
+
+namespace basyx {
+namespace submodel {
+namespace simple {
+
+class GYearMonth
+{
+private:
+  int year;
+  uint8_t month;
+private:
+  Timezone timezone;
+public:
+  GYearMonth(int year, uint8_t month, const Timezone & = Timezone{});
+
+  int getYear() const;
+  void setYear(int year);
+
+  uint8_t getMonth() const;
+  void setMonth(uint8_t month);
+
+  const Timezone &getTimezone() const;
+  void setTimezone(const Timezone &timezone);
+};
+
+}
+}
+}
+#endif /* BASYX_SIMPLE_SDK_GYEARMONTH_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/xsd_types/Time.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/xsd_types/Time.h
new file mode 100644
index 0000000..7c4e9ed
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/xsd_types/Time.h
@@ -0,0 +1,42 @@
+#ifndef BASYX_SIMPLE_SDK_TIME_H
+#define BASYX_SIMPLE_SDK_TIME_H
+
+#include "Timezone.h"
+
+#include <cstdint>
+#include <string>
+
+namespace basyx {
+namespace submodel {
+namespace simple {
+
+/**
+ * Time represents instants of time that recur at the same point in each calendar day, or that occur in some arbitrary calendar day.
+ */
+class Time
+{
+private:
+  uint8_t hours, minutes;
+  float seconds;
+  Timezone timezone;
+public:
+  Time(uint8_t hours, uint8_t minutes, float seconds, const Timezone & timezone = "Z");
+
+  uint8_t getHours() const;
+  void setHours(uint8_t hours);
+
+  uint8_t getMinutes() const;
+  void setMinutes(uint8_t minutes);
+
+  float getSeconds() const;
+  void setSeconds(float seconds);
+
+  const Timezone & getTimezone() const;
+  void setTimezone(const Timezone &);
+};
+
+}
+}
+}
+
+#endif /* BASYX_SIMPLE_SDK_TIME_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/xsd_types/Timezone.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/xsd_types/Timezone.h
new file mode 100644
index 0000000..080e168
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/xsd_types/Timezone.h
@@ -0,0 +1,31 @@
+#ifndef BASYX_SIMPLE_SDK_TIMEZONE_H
+#define BASYX_SIMPLE_SDK_TIMEZONE_H
+
+#include <string>
+
+namespace basyx {
+namespace submodel {
+namespace simple {
+
+class Timezone
+{
+private:
+  std::string timezone;
+
+public:
+  Timezone();
+  Timezone(const std::string &);
+  Timezone(const char*);
+
+  const std::string &getTimezone() const;
+  void setTimezone(const std::string &timezone);
+
+  bool isUTC() const;
+
+  operator const std::string & () const;
+};
+
+}
+}
+}
+#endif /* BASYX_SIMPLE_SDK_TIMEZONE_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/xsd_types/YearMonthDuration.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/xsd_types/YearMonthDuration.h
new file mode 100644
index 0000000..0eb0f2d
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/common/xsd_types/YearMonthDuration.h
@@ -0,0 +1,25 @@
+#ifndef BASYX_SIMPLE_SDK_YEARMONTHDURATION_H
+#define BASYX_SIMPLE_SDK_YEARMONTHDURATION_H
+
+namespace basyx {
+namespace submodel {
+namespace simple {
+
+class YearMonthDuration
+{
+private:
+  int years = 0, months = 0;
+public:
+  YearMonthDuration(int years, int months);
+
+  int getYears() const;
+  int getMonths() const;
+
+  void setYears(const int &);
+  void setMonths(const int &);
+};
+
+}
+}
+}
+#endif /* BASYX_SIMPLE_SDK_YEARMONTHDURATION_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/dataspecification/DataSpecification.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/dataspecification/DataSpecification.h
index bbd5771..c148e01 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/dataspecification/DataSpecification.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/dataspecification/DataSpecification.h
@@ -26,14 +26,19 @@
 	// Inherited via IIdentifiable
 	virtual const std::string & getIdShort() const override;
 	virtual const std::string * const getCategory() const override;
-  void setCategory(const std::string & category) override;
+	void setCategory(const std::string & category) override;
 	virtual simple::LangStringSet & getDescription() override;
 	virtual const simple::LangStringSet & getDescription() const override;
-	virtual const IReferable * const getParent() const override;
+	virtual IReferable * getParent() const override;
+	virtual void setParent(IReferable * parent) override;
 	virtual const AdministrativeInformation & getAdministrativeInformation() const override;
 	virtual AdministrativeInformation & getAdministrativeInformation() override;
 	virtual Identifier getIdentification() const override;
 	virtual bool hasAdministrativeInformation() const override;
+	virtual simple::Reference getReference() const override;
+
+        virtual Key getKey(bool local = true) const override { return ident.getKey(); }
+
 };
 
 }
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/dataspecification/DataSpecificationPhysicalUnit.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/dataspecification/DataSpecificationPhysicalUnit.h
index 379b75c..8dbf3cf 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/dataspecification/DataSpecificationPhysicalUnit.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/dataspecification/DataSpecificationPhysicalUnit.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_SIMPLE_SDK_DATASPECIFICATIONPHYSICALUNIT_H
-#define BASYX_SIMPLE_SDK_DATASPECIFICATIONPHYSICALUNIT_H
+#ifndef BASYX_SUBMODEL_SIMPLE_DATASPECIFICATION_DATASPECIFICATIONPHYSICALUNIT_H
+#define BASYX_SUBMODEL_SIMPLE_DATASPECIFICATION_DATASPECIFICATIONPHYSICALUNIT_H
 
 #include <BaSyx/submodel/api_v2/dataspecification/IDataSpecificationPhysicalUnit.h>
 #include <BaSyx/submodel/simple/common/LangStringSet.h>
@@ -75,4 +75,4 @@
 }
 }
 }
-#endif //BASYX_SIMPLE_SDK_DATASPECIFICATIONPHYSICALUNIT_H
+#endif /* BASYX_SUBMODEL_SIMPLE_DATASPECIFICATION_DATASPECIFICATIONPHYSICALUNIT_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/dataspecification/ValueList.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/dataspecification/ValueList.h
index df22b8c..16306d8 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/dataspecification/ValueList.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/dataspecification/ValueList.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_C_SDK_SIMPLE_VALUELIST_H
-#define BASYX_C_SDK_SIMPLE_VALUELIST_H
+#ifndef BASYX_SUBMODEL_SIMPLE_DATASPECIFICATION_VALUELIST_H
+#define BASYX_SUBMODEL_SIMPLE_DATASPECIFICATION_VALUELIST_H
 
 #include <BaSyx/submodel/api_v2/dataspecification/IValueList.h>
 
@@ -8,21 +8,20 @@
 namespace simple {
 
 class ValueList
-    : public api::IValueList
-{
+    : public api::IValueList {
 public:
-  ValueList() = default;
-  explicit ValueList(const std::vector<simple::ValueReferencePair> & list);
+    ValueList() = default;
+    explicit ValueList(const std::vector<simple::ValueReferencePair>& list);
 
-  void addValueReferencePair(const simple::ValueReferencePair & valueRefPair) override;
-  std::vector<simple::ValueReferencePair> getValueReferencePairs() override;
+    void addValueReferencePair(const simple::ValueReferencePair& valueRefPair) override;
+    std::vector<simple::ValueReferencePair> getValueReferencePairs() override;
 
 private:
-  std::vector<simple::ValueReferencePair> list;
+    std::vector<simple::ValueReferencePair> list;
 };
 
 }
 }
 }
 
-#endif //BASYX_C_SDK_VALUELIST_H
+#endif /* BASYX_SUBMODEL_SIMPLE_DATASPECIFICATION_VALUELIST_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/dataspecification/ValueReferencePair.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/dataspecification/ValueReferencePair.h
index 6e9a484..bbdcfbb 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/dataspecification/ValueReferencePair.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/dataspecification/ValueReferencePair.h
@@ -40,4 +40,4 @@
 }
 }
 
-#endif 
\ No newline at end of file
+#endif /* BASYX_SUBMODEL_SIMPLE_DATASPECIFICATION_VALUEREFERENCEPAIR_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/dataspecification/datatypes--/DataTypeIEC61360.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/dataspecification/datatypes--/DataTypeIEC61360.h
deleted file mode 100644
index dce216f..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/dataspecification/datatypes--/DataTypeIEC61360.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * DataTypeIEC61360.h
- *
- *      Author: wendel
- */
-
-#ifndef BASYX_SUBMODEL_SIMPLE_DATASPECIFICATION_DATATYPES--_DATATYPEIEC61360_H
-#define BASYX_SUBMODEL_SIMPLE_DATASPECIFICATION_DATATYPES--_DATATYPEIEC61360_H
-
-#include <string>
-#include <unordered_map>
-
-#include <BaSyx/util/util.h>
-
-namespace basyx {
-namespace submodel {
-
-	enum class DataTypeIEC61360 : char
-	{
-		Date,
-		String,
-		String_Translatable,
-		Real_Measure,
-		Real_Count,
-		Real_Currency,
-		Boolean,
-		Url,
-		Rational,
-		Rational_Measure,
-		Time,
-		Timestamp
-	};
-}
-}
-
-namespace util {
-	const std::string & to_string(basyx::submodel::DataTypeIEC61360 type);
-
-	template<>
-	basyx::submodel::DataTypeIEC61360 from_string<basyx::submodel::DataTypeIEC61360>(const std::string & str);
-}
-
-#endif /* BASYX_SUBMODEL_SIMPLE_DATASPECIFICATION_DATATYPES--_DATATYPEIEC61360_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/dataspecification/datatypes--/LevelType.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/dataspecification/datatypes--/LevelType.h
deleted file mode 100644
index aba9ad8..0000000
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/dataspecification/datatypes--/LevelType.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * LevelType.h
- *
- *      Author: wendel
- */
-
-#ifndef BASYX_SUBMODEL_SIMPLE_DATASPECIFICATION_DATATYPES--_LEVELTYPE_H
-#define BASYX_SUBMODEL_SIMPLE_DATASPECIFICATION_DATATYPES--_LEVELTYPE_H
-
-#include <unordered_map>
-#include <string>
-
-#include <BaSyx/util/util.h>
-
-namespace basyx {
-namespace submodel {
-
-	enum class LevelType : char
-	{
-	  Min,
-	  Max,
-	  Nom,
-	  Typ
-	};
-}
-}
-
-namespace util {
-
-	const std::string & to_string(basyx::submodel::LevelType levelType);
-
-	template<>
-	basyx::submodel::LevelType from_string<basyx::submodel::LevelType>(const std::string & str);
-}
-
-#endif /* BASYX_SUBMODEL_SIMPLE_DATASPECIFICATION_DATATYPES--_LEVELTYPE_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/parts/ConceptDescription.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/parts/ConceptDescription.h
index 5d8f123..477f71e 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/parts/ConceptDescription.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/parts/ConceptDescription.h
@@ -14,9 +14,9 @@
 
 class ConceptDescription
   : public virtual api::IConceptDescription
-  , public Identifiable
 {
 private:
+	Identifiable identifiable;
 	HasDataSpecification dataSpec;
 	std::vector<std::unique_ptr<api::IReference>> isCaseOf;
 	ElementContainer<api::IDataSpecification> embeddedDataSpecs;
@@ -33,9 +33,30 @@
 	void addDataSpecification(const Reference & reference) override;
 	const std::vector<Reference> getDataSpecificationReference() const override;
 
-  //not inherited
-  void addIsCaseOf(std::unique_ptr<simple::Reference> reference);
-  void addEmbeddedDataSpecification(std::unique_ptr<DataSpecification> data_specification);
+	// Inherited via IReferable
+	virtual const std::string & getIdShort() const override;
+	virtual const std::string * const getCategory() const override;
+	virtual void setCategory(const std::string & category) override;
+	virtual simple::LangStringSet & getDescription() override;
+	virtual const simple::LangStringSet & getDescription() const override;
+	virtual void setParent(api::IReferable * parent) override;
+	virtual IReferable * getParent() const override;
+	virtual simple::Reference getReference() const override;
+
+	// Inherited via IIdentifiable
+	virtual const AdministrativeInformation & getAdministrativeInformation() const override;
+	virtual AdministrativeInformation & getAdministrativeInformation() override;
+
+	virtual Identifier getIdentification() const override;
+
+	virtual bool hasAdministrativeInformation() const override;
+
+	//not inherited
+	void addIsCaseOf(std::unique_ptr<simple::Reference> reference);
+	void addEmbeddedDataSpecification(std::unique_ptr<DataSpecification> data_specification);
+
+        virtual Key getKey(bool local = true) const override { return identifiable.getKey(); }
+	virtual KeyElements getKeyElementType() const override { return KeyElements::ConceptDescription; };
 };
 
 }
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/parts/ConceptDictionary.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/parts/ConceptDictionary.h
index 5cbce0d..813d583 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/parts/ConceptDictionary.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/parts/ConceptDictionary.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_SIMPLE_SDK_CONCEPTDICTIONARY_H
-#define BASYX_SIMPLE_SDK_CONCEPTDICTIONARY_H
+#ifndef BASYX_SUBMODEL_SIMPLE_PARTS_CONCEPTDICTIONARY_H
+#define BASYX_SUBMODEL_SIMPLE_PARTS_CONCEPTDICTIONARY_H
 
 #include <BaSyx/submodel/api_v2/parts/IConceptDictionary.h>
 
@@ -14,22 +14,34 @@
 
 class ConceptDictionary
     : public api::IConceptDictionary
-    , public Referable
 {
 private:
-  ElementContainer<api::IConceptDescription> conecpt_descriptions;
-
+	Referable referable;
+	ElementContainer<api::IConceptDescription> conceptDescriptions;
 public:
-  ConceptDictionary(const std::string & idShort);
+	ConceptDictionary(const std::string & idShort);
 
-  //inherited via IConceptDictionary
-  const api::IElementContainer<api::IConceptDescription> & getConceptDescriptions() const override;
+	//inherited via IConceptDictionary
+	const api::IElementContainer<api::IConceptDescription> & getConceptDescriptions() const override;
 
-  //not inherited
-  void addConceptDescription(std::unique_ptr<ConceptDescription> description);
+	// inherited via IReferable
+	virtual const std::string & getIdShort() const override;
+	virtual const std::string * const getCategory() const override;
+	virtual void setCategory(const std::string & category) override;
+	virtual simple::LangStringSet & getDescription() override;
+	virtual const simple::LangStringSet & getDescription() const override;
+	virtual void setParent(api::IReferable * parent) override;
+	virtual IReferable * getParent() const override;
+	virtual simple::Reference getReference() const override;
+
+	//not inherited
+	void addConceptDescription(std::unique_ptr<ConceptDescription> description);
+
+        virtual Key getKey(bool local = true) const override { return referable.getKey(); }
+	virtual KeyElements getKeyElementType() const override { return KeyElements::ConceptDictionary; };
 };
 
 }
 }
 }
-#endif //BASYX_SIMPLE_SDK_CONCEPTDICTIONARY_H
+#endif /* BASYX_SUBMODEL_SIMPLE_PARTS_CONCEPTDICTIONARY_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/parts/View.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/parts/View.h
index 76966c1..6de2420 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/parts/View.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/parts/View.h
@@ -1,5 +1,5 @@
-#ifndef BASYX_SIMPLE_SDK_VIEW_H
-#define BASYX_SIMPLE_SDK_VIEW_H
+#ifndef BASYX_SUBMODEL_SIMPLE_PARTS_VIEW_H
+#define BASYX_SUBMODEL_SIMPLE_PARTS_VIEW_H
 
 #include <BaSyx/submodel/api_v2/parts/IView.h>
 
@@ -13,14 +13,15 @@
 
 class View
   : public virtual api::IView
-  , public virtual HasDataSpecification
-  , public virtual Referable
 {
 private:
+	HasDataSpecification dataSpec;
+	Referable referable;
+
   ElementContainer<api::IReferable> contained_elements;
   Reference semanticId;
 public:
-  View(const std::string & idShort, const Referable * parent = nullptr);
+  View(const std::string & idShort, Referable * parent = nullptr);
 
   //Inherited via api::IView
   const api::IElementContainer<IReferable> & getContainedElements() const override;
@@ -28,12 +29,29 @@
   //not inherited
   void addContainedElement(std::unique_ptr<Referable> referable);
 
+  // Inherited via IHasDataSpecification
+  virtual void addDataSpecification(const simple::Reference & reference) override;
+  virtual const std::vector<simple::Reference> getDataSpecificationReference() const override;
+
   //inherited via IHasSemantics
   const api::IReference & getSemanticId() const override;
   void setSemanticId(const api::IReference & reference) override;
+
+  // Inherited via IReferable
+  virtual const std::string & getIdShort() const override;
+  virtual const std::string * const getCategory() const override;
+  virtual void setCategory(const std::string & category) override;
+  virtual simple::LangStringSet & getDescription() override;
+  virtual const simple::LangStringSet & getDescription() const override;
+  virtual void setParent(api::IReferable * parent) override;
+  virtual IReferable * getParent() const override;
+  virtual simple::Reference getReference() const override;
+
+  virtual Key getKey(bool local = true) const override { return referable.getKey(); }
+  virtual KeyElements getKeyElementType() const override { return KeyElements::View; };
 };
 
 }
 }
 }
-#endif //BASYX_SIMPLE_SDK_VIEW_H
+#endif /* BASYX_SUBMODEL_SIMPLE_PARTS_VIEW_H */
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/qualifier/AdministrativeInformation.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/qualifier/AdministrativeInformation.h
index 7003666..7f0903e 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/qualifier/AdministrativeInformation.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/qualifier/AdministrativeInformation.h
@@ -7,18 +7,18 @@
 #ifndef BASYX_SUBMODEL_SIMPLE_QUALIFIER_ADMINISTRATIVEINFORMATION_H
 #define BASYX_SUBMODEL_SIMPLE_QUALIFIER_ADMINISTRATIVEINFORMATION_H
 
-//#include <BaSyx/submodel/api_v2/qualifier/IAdministrativeInformation.h>
 #include <BaSyx/submodel/simple/qualifier/HasDataSpecification.h>
+#include <BaSyx/submodel/api_v2/qualifier/IAdministrativeInformation.h>
 
 namespace basyx {
 namespace submodel {
 namespace simple {
 
-class AdministrativeInformation : public api::IHasDataSpecification
+class AdministrativeInformation
+  : public api::IAdministrativeInformation
+  , public HasDataSpecification
 {
 private:
-	HasDataSpecification hasDataSpecification;
-
 	std::string version;
 	std::string revision;
 public:
@@ -26,22 +26,18 @@
 
 	AdministrativeInformation();
 	AdministrativeInformation(const std::string & version, const std::string & revision);
-//	AdministrativeInformation(const IAdministrativeInformation & other);
+	explicit AdministrativeInformation(const IAdministrativeInformation & other);
 
-	void setVersion(const std::string & version);
-	void setRevision(const std::string & revision);
+	void setVersion(const std::string & version) override;
+	void setRevision(const std::string & revision) override;
 
-	inline bool hasVersion() const { return version.empty(); };
-	inline bool hasRevision() const { return revision.empty(); };
+	inline bool hasVersion() const override { return !version.empty(); };
+	inline bool hasRevision() const override { return !revision.empty(); };
 
 	inline bool exists() const noexcept { return !version.empty() && !revision.empty(); };
 
-	virtual std::string getVersion() const;
-	virtual std::string getRevision() const;
-
-	// Inherited via IHasDataSpecification
-	virtual void addDataSpecification(const Reference & reference) override;
-	const std::vector<Reference> getDataSpecificationReference() const override;
+	virtual const std::string * const getVersion() const override;
+	virtual const std::string * const getRevision() const override;
 };
 
 }
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/qualifier/Identifiable.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/qualifier/Identifiable.h
index c44b4ad..ec717af 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/qualifier/Identifiable.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/qualifier/Identifiable.h
@@ -21,7 +21,7 @@
 
 	// Constructors
 	Identifiable(const std::string & idShort, const Identifier & identifier);
-  explicit Identifiable(const api::IIdentifiable & other);
+	explicit Identifiable(const api::IIdentifiable & other);
 
 	bool hasAdministrativeInformation() const noexcept override;
 
@@ -31,7 +31,7 @@
 
 	Identifier getIdentification() const override;
 
-  void setAdministrativeInformation(const AdministrativeInformation & administrativeInformation);
+	void setAdministrativeInformation(const AdministrativeInformation & administrativeInformation);
 };
 
 }
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/qualifier/Qualifiable.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/qualifier/Qualifiable.h
index 6521a47..74016be 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/qualifier/Qualifiable.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/qualifier/Qualifiable.h
@@ -3,6 +3,7 @@
 
 #include <BaSyx/submodel/api_v2/qualifier/IQualifiable.h>
 
+#include <BaSyx/submodel/simple/constraint/Qualifier.h>
 
 namespace basyx {
 namespace submodel {
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/qualifier/Referable.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/qualifier/Referable.h
index 22127b8..86ec5f4 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/qualifier/Referable.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/qualifier/Referable.h
@@ -15,12 +15,14 @@
 	std::string idShort;
 	std::string category;
 	LangStringSet description;
-	const IReferable * const parent;
+	IReferable * parent;
+
+	KeyElements keyElementType;
 public:
 	virtual ~Referable() = default;
 
 	// Constructors
-	Referable(const std::string & idShort, const Referable * parent = nullptr);
+	Referable(const std::string & idShort, Referable * parent = nullptr);
 	Referable(const IReferable & other);
 
 	// Inherited via IReferable
@@ -29,7 +31,8 @@
 	virtual LangStringSet & getDescription() override;
 	virtual const LangStringSet & getDescription() const override;
 
-	virtual const IReferable * const getParent() const override;
+	virtual void setParent(IReferable * parent) override;
+	virtual IReferable * getParent() const override;
 
 	// not inherited
 	void setIdShort(const std::string & shortID);
@@ -38,6 +41,11 @@
 	bool hasParent() const noexcept;
 	bool hasDescription() const noexcept;
 	bool hasCategory() const noexcept;
+
+	simple::Reference getReference() const override;
+	simple::Key getKey(bool local = true) const override;
+
+	KeyElements getKeyElementType() const override;
 };
 
 
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/reference/Key.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/reference/Key.h
index ddadb29..8fca8be 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/reference/Key.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/reference/Key.h
@@ -3,7 +3,7 @@
 
 #include <BaSyx/submodel/enumerations/KeyType.h>
 #include <BaSyx/submodel/enumerations/KeyElements.h>
-#include <BaSyx/submodel/api_v2/reference/IKey.h>
+//#include <BaSyx/submodel/api_v2/reference/IKey.h>
 
 #include <string>
 
@@ -11,7 +11,7 @@
 namespace submodel {
 namespace simple {
 
-class Key : public api::IKey
+class Key // : public api::IKey
 {
 private:
 	KeyElements type;
@@ -24,10 +24,13 @@
 	bool operator!=(const Key & other) const;
 	inline bool operator==(const Key & other) const { return !(*this != other); };
 public:
-	KeyElements getType() const noexcept override;
-	KeyType getIdType() const noexcept override;
-	bool isLocal() const noexcept override;
-	std::string getValue() const noexcept override;
+	KeyElements getType() const noexcept;
+	KeyType getIdType() const noexcept;
+	bool isLocal() const noexcept;
+	std::string getValue() const noexcept;
+
+	bool isGlobalKey() const noexcept;
+	bool isModelKey() const noexcept;
 };
 
 }
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/reference/Reference.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/reference/Reference.h
index 8a8e0f7..0ddbe82 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/reference/Reference.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/reference/Reference.h
@@ -2,7 +2,6 @@
 #define BASYX_SUBMODEL_SIMPLE_REFERENCE_REFERENCE_H
 
 #include <BaSyx/submodel/api_v2/reference/IReference.h>
-#include <BaSyx/submodel/api_v2/qualifier/IIdentifiable.h>
 
 #include <BaSyx/submodel/simple/reference/Key.h>
 
@@ -43,8 +42,6 @@
 	void addKey(const Key & key) override;
 
 	bool empty() const override;
-public:
-	static Reference FromIdentifiable(KeyElements keyElementType, const api::IIdentifiable & identifiable);
 };
 
 }
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/submodelelement/SubmodelElement.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/submodelelement/SubmodelElement.h
index 05c55fe..6a1670b 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/submodelelement/SubmodelElement.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/submodelelement/SubmodelElement.h
@@ -6,41 +6,58 @@
 #include <BaSyx/submodel/simple/qualifier/HasDataSpecification.h>
 #include <BaSyx/submodel/api_v2/qualifier/IHasKind.h>
 #include <BaSyx/submodel/simple/qualifier/Referable.h>
+#include <BaSyx/submodel/simple/qualifier/Qualifiable.h>
 
 
 namespace basyx {
 namespace submodel {
 namespace simple {
 
-class SubmodelElement : public virtual api::ISubmodelElement
+class SubmodelElement
+  : public api::ISubmodelElement
 {
 private:
 	HasDataSpecification dataSpecification;
 	ModelingKind kind;
 	Reference semanticId;
 	Referable referable;
+	Qualifiable qualifiable;
+	ModelTypes modelType;
 public:
 	SubmodelElement(const std::string & idShort, ModelingKind kind = ModelingKind::Instance);
 
-	virtual ~SubmodelElement() = default;
+	~SubmodelElement() = default;
 
 	// Inherited via IHasDataSemantics
-	virtual const api::IReference & getSemanticId() const override;
-	void setSemanticId(Reference reference);
+	const api::IReference & getSemanticId() const override;
+	void setSemanticId(const api::IReference & reference) override;
 
 	// Inherited via IHasDataSpecification
-	virtual void addDataSpecification(const Reference & reference) override;
-	virtual const std::vector<Reference> getDataSpecificationReference() const override;
+	void addDataSpecification(const Reference & reference) override;
+	const std::vector<Reference> getDataSpecificationReference() const override;
 
 	// Inherited via IReferable
-	virtual const std::string & getIdShort() const override;
-	virtual const std::string * const getCategory() const override;
-	virtual simple::LangStringSet & getDescription() override;
-	virtual const simple::LangStringSet & getDescription() const override;
-	virtual const IReferable * const getParent() const override;
+	const std::string & getIdShort() const override;
+	const std::string * const getCategory() const override;
+  	void setCategory(const std::string & category) override;
+	simple::LangStringSet & getDescription() override;
+	const simple::LangStringSet & getDescription() const override;
+	IReferable * getParent() const override;
+	void setParent(IReferable * parent) override;
+	Key getKey(bool local) const override;
+	simple::Reference getReference() const override;
 
 	// Inherited via IHasKind
-	virtual ModelingKind getKind() const override;
+	ModelingKind getKind() const override;
+
+	// Inherited via IQualifiable
+	std::vector<Formula> getFormulas() const override;
+	std::vector<Qualifier> getQualifiers() const override;
+	void addFormula(const api::IFormula & formula) override;
+	void addQualifier(const api::IQualifier & qualifier) override;
+
+  // Inherited vie IModelType
+  ModelTypes GetModelType() const override;
 };
 
 }
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/submodelelement/property/Property.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/submodelelement/property/Property.h
index d254313..2eb2efb 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/submodelelement/property/Property.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/submodelelement/property/Property.h
@@ -13,7 +13,9 @@
 namespace simple {
 
 template<typename T>
-class Property : public SubmodelElement, public IProperty
+class Property
+  : public SubmodelElement
+  , public virtual api::IProperty
 {
 private:
 	std::string valueType;
@@ -63,10 +65,12 @@
 		return &this->valueId;
 	}
 
-	virtual void setValueId(const Reference & valueId) override
+	virtual void setValueId(const api::IReference & valueId) override
 	{
 		this->valueId = valueId;
 	}
+
+  virtual KeyElements getKeyElementType() const override { return KeyElements::Property; };
 };
 
 }
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/util/tools/StringTools.h b/sdks/c++/basys.sdk.cc/include/BaSyx/util/tools/StringTools.h
index 315d3c0..f4a5bb0 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/util/tools/StringTools.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/util/tools/StringTools.h
@@ -29,7 +29,7 @@
 	 * Assumes that target is big enough to carry the content of str
 	 */
 	static std::size_t toArray(std::string const& str, char* target) {
-		CoderTools::setInt32(target, 0, str.length());
+		CoderTools::setInt32(target, 0, static_cast<uint32_t>(str.length()));
 		target += 4;
 		std::memcpy(target, str.c_str(), str.length());
 		return str.length() + 4;
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/vab/backend/connector/JSONProvider.h b/sdks/c++/basys.sdk.cc/include/BaSyx/vab/backend/connector/JSONProvider.h
index b38d701..3d077a0 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/vab/backend/connector/JSONProvider.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/vab/backend/connector/JSONProvider.h
@@ -109,9 +109,7 @@
 
     std::string serializeSuccess()
     {
-        nlohmann::json retJson { { "success", true } };
-
-        return retJson.dump(4);
+        return "";
 	}
 };
 
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/vab/backend/connector/native/BaSyxConnector.h b/sdks/c++/basys.sdk.cc/include/BaSyx/vab/backend/connector/native/BaSyxConnector.h
index fc19d2a..686b08f 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/vab/backend/connector/native/BaSyxConnector.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/vab/backend/connector/native/BaSyxConnector.h
@@ -22,7 +22,7 @@
 
     class NativeConnector : public IBaSyxConnector {
     public:
-        static constexpr std::size_t default_buffer_length = 4096;
+        static constexpr std::size_t default_buffer_length = 8192;
 	private:
 		basyx::net::tcp::Socket socket;
 		std::array<char, default_buffer_length> buffer;
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/vab/provider/VABModelProvider.h b/sdks/c++/basys.sdk.cc/include/BaSyx/vab/provider/VABModelProvider.h
index e7e2d61..0349585 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/vab/provider/VABModelProvider.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/vab/provider/VABModelProvider.h
@@ -17,7 +17,7 @@
 
 class VABModelProvider : public vab::core::IModelProvider
 {
-private:
+protected:
 	basyx::log log;
 	basyx::object elements;
 public:
diff --git a/sdks/c++/basys.sdk.cc/src/aas/BaSyxAASConfig.cmake.in b/sdks/c++/basys.sdk.cc/src/aas/BaSyxAASConfig.cmake.in
deleted file mode 100644
index 74d9791..0000000
--- a/sdks/c++/basys.sdk.cc/src/aas/BaSyxAASConfig.cmake.in
+++ /dev/null
@@ -1,12 +0,0 @@
-include(CMakeFindDependencyMacro)
-
-set(BASYX_AAS_VERSION_STRING "@PROJECT_VERSION@")
-
-find_dependency(BaSyxShared)
-find_dependency(BaSyxAbstraction)
-find_dependency(BaSyxVAB)
-find_dependency(BaSyxSubmodel)
-
-include("${CMAKE_CURRENT_LIST_DIR}/@BASYX_AAS_LIBRARY_NAME@Targets.cmake")
-
-@PACKAGE_INIT@
diff --git a/sdks/c++/basys.sdk.cc/src/aas/CMakeLists.txt b/sdks/c++/basys.sdk.cc/src/aas/CMakeLists.txt
deleted file mode 100644
index aae27db..0000000
--- a/sdks/c++/basys.sdk.cc/src/aas/CMakeLists.txt
+++ /dev/null
@@ -1,98 +0,0 @@
-###############################################
-###              BaSyx::AAS                 ###
-###############################################
-include(CMakePackageConfigHelpers)
-
-set (BASYX_AAS_LIB_SUFFIX "AAS")
-
-set (BASYX_AAS_LIBRARY_NAME "${PROJECT_SHORTNAME}${BASYX_AAS_LIB_SUFFIX}")
-
-set (BASYX_AAS_INCLUDE_DIR "${BASYX_INCLUDE_DIR}/BaSyx/aas")
-set (PROJECT_INCLUDE_DIR BASYX_AAS_INCLUDE_DIR)
-
-add_library(${BASYX_AAS_LIB_SUFFIX})
-
-set_target_properties(${BASYX_AAS_LIB_SUFFIX} PROPERTIES VERSION ${PROJECT_VERSION})
-set_target_properties(${BASYX_AAS_LIB_SUFFIX} PROPERTIES SOVERSION ${BASYX_PACKAGE_VERSION_MAJOR})
-set_target_properties(${BASYX_AAS_LIB_SUFFIX} PROPERTIES PREFIX "${CMAKE_STATIC_LIBRARY_PREFIX}${PROJECT_SHORTNAME}")
-
-target_include_directories(${BASYX_AAS_LIB_SUFFIX}
-    INTERFACE ${CMAKE_INSTALL_PREFIX}/include
-    ${CMAKE_INSTALL_PREFIX}/include/${PROJECT_SHORTNAME})
-
-target_sources(${BASYX_AAS_LIB_SUFFIX}
-  PRIVATE
-    ${CMAKE_CURRENT_SOURCE_DIR}/aas/map/constant_definitions.cpp
-    ${BASYX_AAS_INCLUDE_DIR}/api/manager/IAssetAdministrationShellManager.h
-    ${BASYX_AAS_INCLUDE_DIR}/api/metamodel/IAssetAdministrationShell.h
-    ${BASYX_AAS_INCLUDE_DIR}/api/parts/IAsset.h
-    ${BASYX_AAS_INCLUDE_DIR}/api/parts/IConceptDictionary.h
-    ${BASYX_AAS_INCLUDE_DIR}/api/parts/IView.h
-    ${BASYX_AAS_INCLUDE_DIR}/api/policypoints/IAccessControlPolicyPoints.h
-    ${BASYX_AAS_INCLUDE_DIR}/api/security/ISecurity.h
-#  ${CMAKE_CURRENT_SOURCE_DIR}/aas/connected/aas/ConnectedAssetAdministrationShell.cpp
-#    ${BASYX_AAS_INCLUDE_DIR}/connected/aas/ConnectedAssetAdministrationShell.h
-#  ${CMAKE_CURRENT_SOURCE_DIR}/aas/connected/aas/ConnectedAssetAdministrationShellManager.cpp
-#    ${BASYX_AAS_INCLUDE_DIR}/connected/aas/ConnectedAssetAdministrationShellManager.h
-    ${CMAKE_CURRENT_SOURCE_DIR}/aas/map/descriptor/ModelDescriptor.cpp
-    ${BASYX_AAS_INCLUDE_DIR}/map/descriptor/ModelDescriptor.h
-    ${CMAKE_CURRENT_SOURCE_DIR}/aas/map/descriptor/SubModelDescriptor.cpp
-    ${BASYX_AAS_INCLUDE_DIR}/map/descriptor/SubModelDescriptor.h
-    ${CMAKE_CURRENT_SOURCE_DIR}/aas/map/metamodel/AssetAdministrationShell.cpp
-    ${BASYX_AAS_INCLUDE_DIR}/map/metamodel/AssetAdministrationShell.h
-    ${CMAKE_CURRENT_SOURCE_DIR}/aas/map/manager/AssetAdministrationShellManager.cpp
-    ${BASYX_AAS_INCLUDE_DIR}/map/manager/AssetAdministrationShellManager.h
-    ${CMAKE_CURRENT_SOURCE_DIR}/aas/map/modelurn/ModelUrn.cpp
-    ${BASYX_AAS_INCLUDE_DIR}/map/modelurn/ModelUrn.h
-    ${CMAKE_CURRENT_SOURCE_DIR}/aas/map/parts/Asset.cpp
-    ${BASYX_AAS_INCLUDE_DIR}/map/parts/Asset.h
-    ${CMAKE_CURRENT_SOURCE_DIR}/aas/map/parts/ConceptDictionary.cpp
-    ${BASYX_AAS_INCLUDE_DIR}/map/parts/ConceptDictionary.h
-    ${CMAKE_CURRENT_SOURCE_DIR}/aas/map/parts/View.cpp
-    ${BASYX_AAS_INCLUDE_DIR}/map/parts/View.h
-    ${CMAKE_CURRENT_SOURCE_DIR}/aas/map/security/Security.cpp
-    ${BASYX_AAS_INCLUDE_DIR}/map/security/Security.h
-)
-
-
-target_include_directories(${BASYX_AAS_LIB_SUFFIX} PRIVATE ${PROJECT_SOURCE_DIR})
-target_link_libraries(${BASYX_AAS_LIB_SUFFIX} PUBLIC BaSyx::Shared BaSyx::Abstraction BaSyx::VAB BaSyx::Submodel)
-
-add_library(basyx::aas ALIAS ${BASYX_AAS_LIB_SUFFIX})
-add_library(${PROJECT_SHORTNAME}::${BASYX_AAS_LIB_SUFFIX} ALIAS ${BASYX_AAS_LIB_SUFFIX})
-
-diagnostics_print(${BASYX_AAS_LIB_SUFFIX})
-
-###############################################
-###           Install section               ###
-###############################################
-if(${BASYX_INSTALL_SDK})
-configure_package_config_file(
-    ${CMAKE_CURRENT_SOURCE_DIR}/${BASYX_AAS_LIBRARY_NAME}Config.cmake.in
-    ${CMAKE_CURRENT_BINARY_DIR}/${BASYX_AAS_LIBRARY_NAME}Config.cmake
-    INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${BASYX_AAS_LIBRARY_NAME}
-    PATH_VARS
-    CMAKE_INSTALL_PREFIX
-)
-
-install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${BASYX_AAS_LIBRARY_NAME}Config.cmake
-        DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${BASYX_AAS_LIBRARY_NAME}
-        )
-
-install(EXPORT ${BASYX_AAS_LIB_SUFFIX}Targets
-        NAMESPACE ${PROJECT_SHORTNAME}::
-        FILE ${BASYX_AAS_LIBRARY_NAME}Targets.cmake
-        DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${BASYX_AAS_LIBRARY_NAME}
-        )
-
-install(TARGETS ${BASYX_AAS_LIB_SUFFIX}
-        EXPORT ${BASYX_AAS_LIB_SUFFIX}Targets
-        ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
-        LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
-        )
-
-install(DIRECTORY "${BASYX_INCLUDE_DIR}/${PROJECT_SHORTNAME}/aas"
-        DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_SHORTNAME}"
-        FILES_MATCHING PATTERN "*.h"
-        )
-endif()
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/src/aas/aas/connected/aas/ConnectedAssetAdministrationShell.cpp b/sdks/c++/basys.sdk.cc/src/aas/aas/connected/aas/ConnectedAssetAdministrationShell.cpp
deleted file mode 100644
index 0521f0b..0000000
--- a/sdks/c++/basys.sdk.cc/src/aas/aas/connected/aas/ConnectedAssetAdministrationShell.cpp
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * ConnectedAssetAdministrationShell.cpp
- *
- *      Author: wendel
- */
-
-#include "BaSyx/aas/connected/ConnectedAssetAdministrationShell.h"
-
-
-namespace basyx {
-namespace aas {
-namespace backend {
-
-ConnectedAssetAdministrationShell::ConnectedAssetAdministrationShell(std::shared_ptr<vab::core::proxy::IVABElementProxy> proxy, std::shared_ptr<api::manager::IAssetAdministrationShellManager> manager) :
-  ConnectedVABModelMap(proxy),
-  manager(manager)
-{}
-
-basyx::specificCollection_t<submodel::IReference> ConnectedAssetAdministrationShell::getDataSpecificationReferences() const
-{
-  return basyx::specificCollection_t<submodel::IReference>();
-}
-
-std::string ConnectedAssetAdministrationShell::getIdShort() const
-{
-  return std::string();
-}
-
-std::string ConnectedAssetAdministrationShell::getCategory() const
-{
-  return std::string();
-}
-
-submodel::Description ConnectedAssetAdministrationShell::getDescription() const
-{
-  return submodel::Description("","");
-}
-
-std::shared_ptr<submodel::IReference> ConnectedAssetAdministrationShell::getParent() const
-{
-  return std::shared_ptr<submodel::IReference>();
-}
-
-std::shared_ptr<submodel::IAdministrativeInformation> ConnectedAssetAdministrationShell::getAdministration() const
-{
-  return nullptr;
-}
-
-std::shared_ptr<submodel::IIdentifier> ConnectedAssetAdministrationShell::getIdentification() const
-{
-  return std::shared_ptr<submodel::IIdentifier>();
-}
-
-basyx::specificMap_t<submodel::ISubModel> ConnectedAssetAdministrationShell::getSubModels() const
-{
-  return basyx::specificMap_t<submodel::ISubModel>();
-}
-
-void ConnectedAssetAdministrationShell::addSubModel(const descriptor::SubModelDescriptor & subModelDescriptor)
-{}
-
-std::shared_ptr<security::ISecurity> ConnectedAssetAdministrationShell::getSecurity() const
-{
-  return std::shared_ptr<security::ISecurity>();
-}
-
-std::shared_ptr<submodel::IReference> ConnectedAssetAdministrationShell::getDerivedFrom() const
-{
-  return std::shared_ptr<submodel::IReference>();
-}
-
-std::shared_ptr<aas::IAsset> ConnectedAssetAdministrationShell::getAsset() const
-{
-  return std::shared_ptr<aas::IAsset>();
-}
-
-void ConnectedAssetAdministrationShell::setSubmodels(const basyx::specificCollection_t<descriptor::SubModelDescriptor> & submodels)
-{}
-
-basyx::specificCollection_t<descriptor::SubModelDescriptor> ConnectedAssetAdministrationShell::getSubModelDescriptors() const
-{
-  return basyx::specificCollection_t<descriptor::SubModelDescriptor>();
-}
-
-basyx::specificCollection_t<IView> ConnectedAssetAdministrationShell::getViews() const
-{
-  return basyx::specificCollection_t<IView>();
-}
-
-basyx::specificCollection_t<IConceptDictionary> ConnectedAssetAdministrationShell::getConceptDictionary() const
-{
-  return basyx::specificCollection_t<IConceptDictionary>();
-}
-
-
-}
-}
-}
-
diff --git a/sdks/c++/basys.sdk.cc/src/aas/aas/connected/aas/ConnectedAssetAdministrationShellManager.cpp b/sdks/c++/basys.sdk.cc/src/aas/aas/connected/aas/ConnectedAssetAdministrationShellManager.cpp
deleted file mode 100644
index e3cf9a4..0000000
--- a/sdks/c++/basys.sdk.cc/src/aas/aas/connected/aas/ConnectedAssetAdministrationShellManager.cpp
+++ /dev/null
@@ -1,7 +0,0 @@
-/*
- * ConnectedAssetAdministrationShellManager.cpp
- *
- *      Author: wendel
- */
-
-#include "BaSyx/aas/connected/ConnectedAssetAdministrationShellManager.h"
diff --git a/sdks/c++/basys.sdk.cc/src/aas/aas/connected/aas/dataspecification/IDataSpecification.h b/sdks/c++/basys.sdk.cc/src/aas/aas/connected/aas/dataspecification/IDataSpecification.h
deleted file mode 100644
index 64a8866..0000000
--- a/sdks/c++/basys.sdk.cc/src/aas/aas/connected/aas/dataspecification/IDataSpecification.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * IDataSpecification.h
- *
- *      Author: wendel
- */
-
-#ifndef BASYX_METAMODEL_IDATASPECIFICATION_H_
-#define BASYX_METAMODEL_IDATASPECIFICATION_H_
-
-#include "aas/reference/IReference.h"
-
-#include "BaSyx/types.h"
-
-#include <string>
-namespace basyx {
-namespace aas {
-namespace backend {
-namespace connected {
-namespace dataspecification {
-
-namespace PathSpecification
-{
-long serialVersionUID = 1L;
-std::string PREFERREDNAME = "preferredName";
-std::string SHORTNAME = "shortName";
-std::string UNIT = "unit";
-std::string UNITID = "unitId";
-std::string SOURCEOFDEFINITION = "sourceOfDefinition";
-std::string SYMBOL = "symbol";
-std::string DATATYPE = "dataType";
-std::string DEFINITION = "definition";
-std::string VALUEFORMAT = "valueFormat";
-std::string VALUELIST = "valueList";
-std::string CODE = "code";
-}
-
-class IDataSpecification
-{
-public:
-  virtual ~IDataSpecification() = default;
-
-  virtual std::string getPreferredName() const = 0;
-  virtual std::string getShortName() const = 0;
-  virtual std::string getUnit() const = 0;
-  //virtual IReference getUnitId() const = 0;
-  virtual std::string getSourceOfDefinition() const = 0;
-  virtual std::string getSymbol() const = 0;
-  virtual std::string getDataType() const = 0;
-  virtual std::string getDefinition() const = 0;
-  virtual std::string getValueFormat() const = 0;
-  virtual std::string getValueList() const = 0;
-  virtual std::string getCode() const = 0;
-
-  virtual void setPreferredName(const std::string & preferredName) = 0;
-  virtual void setShortName(const std::string & shortName) = 0;
-  virtual void setUnit(const std::string & uni) = 0;
-  virtual void setUnitId(const IReference & unitId) = 0;
-  virtual void setSourceOfDefinition(const std::string & sourceOfDefinition) = 0;
-  virtual void setSymbol(const std::string & symbol) = 0;
-  virtual void setDataType(const std::string & dataType) = 0;
-  virtual void setDefinition(const std::string & definition) = 0;
-  virtual void setValueFormat(const std::string & valueFormat) = 0;
-  virtual void setValueList(const basyx::object & obj) = 0;
-  virtual void setCode(const basyx::object & obj) = 0;
-};
-
-#endif
-}
-}
-}
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/aas/aas/map/constant_definitions.cpp b/sdks/c++/basys.sdk.cc/src/aas/aas/map/constant_definitions.cpp
deleted file mode 100644
index 06148e2..0000000
--- a/sdks/c++/basys.sdk.cc/src/aas/aas/map/constant_definitions.cpp
+++ /dev/null
@@ -1,29 +0,0 @@
-#include <BaSyx/aas/api/parts/IConceptDictionary.h>
-#include <BaSyx/aas/api/parts/IAsset.h>
-#include <BaSyx/aas/api/parts/IView.h>
-#include <BaSyx/aas/api/security/ISecurity.h>
-#include <BaSyx/aas/api/metamodel/IAssetAdministrationShell.h>
-
-namespace basyx {
-namespace aas {
-
-constexpr char IConceptDictionary::Path::ConceptDescription[];
-constexpr char IConceptDictionary::Path::ConceptDescriptions[];
-
-constexpr char IAsset::Path::AssetIdentificationModel[];
-constexpr char IAsset::Path::BillOfMaterial[];
-constexpr char IAsset::Path::ModelType[];
-
-constexpr char IView::Path::ModelType[];
-constexpr char IView::Path::ContainedElement[];
-
-constexpr char ISecurity::Path::AccessControlPolicyPoints[];
-constexpr char ISecurity::Path::TrustAnchor[];
-
-constexpr char IAssetAdministrationShell::Path::DerivedFrom[];
-constexpr char IAssetAdministrationShell::Path::ModelType[];
-constexpr char IAssetAdministrationShell::Path::Security[];
-
-
-}
-}
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/src/aas/aas/map/descriptor/ModelDescriptor.cpp b/sdks/c++/basys.sdk.cc/src/aas/aas/map/descriptor/ModelDescriptor.cpp
deleted file mode 100644
index dd87e53..0000000
--- a/sdks/c++/basys.sdk.cc/src/aas/aas/map/descriptor/ModelDescriptor.cpp
+++ /dev/null
@@ -1,7 +0,0 @@
-/*
- * ModelDescriptor.cpp
- *
- *      Author: wendel
- */
-
-#include "BaSyx/aas/map/descriptor/ModelDescriptor.h"
diff --git a/sdks/c++/basys.sdk.cc/src/aas/aas/map/descriptor/SubModelDescriptor.cpp b/sdks/c++/basys.sdk.cc/src/aas/aas/map/descriptor/SubModelDescriptor.cpp
deleted file mode 100644
index b2ecfac..0000000
--- a/sdks/c++/basys.sdk.cc/src/aas/aas/map/descriptor/SubModelDescriptor.cpp
+++ /dev/null
@@ -1,7 +0,0 @@
-/*
- * SubModelDescriptor.cpp
- *
- *      Author: wendel
- */
-
-#include "BaSyx/aas/map/descriptor/SubModelDescriptor.h"
diff --git a/sdks/c++/basys.sdk.cc/src/aas/aas/map/manager/AssetAdministrationShellManager.cpp b/sdks/c++/basys.sdk.cc/src/aas/aas/map/manager/AssetAdministrationShellManager.cpp
deleted file mode 100644
index f1d9bbe..0000000
--- a/sdks/c++/basys.sdk.cc/src/aas/aas/map/manager/AssetAdministrationShellManager.cpp
+++ /dev/null
@@ -1,7 +0,0 @@
-/*
- * AssetAdministrationShellManager.cpp
- *
- *      Author: wendel
- */
-
-#include "BaSyx/aas/map/manager/AssetAdministrationShellManager.h"
diff --git a/sdks/c++/basys.sdk.cc/src/aas/aas/map/metamodel/AssetAdministrationShell.cpp b/sdks/c++/basys.sdk.cc/src/aas/aas/map/metamodel/AssetAdministrationShell.cpp
deleted file mode 100644
index 94ae032..0000000
--- a/sdks/c++/basys.sdk.cc/src/aas/aas/map/metamodel/AssetAdministrationShell.cpp
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * AssetAdministrationShell.cpp
- *
- *      Author: wendel
- */
-
-#include "BaSyx/aas/map/metamodel/AssetAdministrationShell.h"
-
-#include <BaSyx/aas/map/security/Security.h>
-#include <BaSyx/submodel/map/reference/Reference.h>
-
-namespace basyx {
-namespace aas {
-
-using namespace submodel;
-
-AssetAdministrationShell::AssetAdministrationShell()
-  : vab::ElementMap()
-  , ModelType(IAssetAdministrationShell::Path::ModelType)
-{}
-
-AssetAdministrationShell::AssetAdministrationShell(basyx::object obj)
-  : vab::ElementMap(obj)
-  , ModelType(IAssetAdministrationShell::Path::ModelType)
-{}
-
-AssetAdministrationShell::AssetAdministrationShell(std::shared_ptr<submodel::IReference> parentAAS)
-  : vab::ElementMap()
-  , ModelType(IAssetAdministrationShell::Path::ModelType)
-{
-  this->setDerivedFrom(parentAAS);
-}
-
-std::shared_ptr<ISecurity> AssetAdministrationShell::getSecurity() const
-{
-  return std::make_shared<Security>(this->map.getProperty(IAssetAdministrationShell::Path::Security));
-}
-
-void AssetAdministrationShell::setSecurity(std::shared_ptr<ISecurity> security) const
-{
-  this->map.insertKey(IAssetAdministrationShell::Path::Security, Security(*security).getMap());
-}
-
-std::shared_ptr<submodel::IReference> AssetAdministrationShell::getDerivedFrom() const
-{
-  return std::make_shared<Reference>(this->map.getProperty(IAssetAdministrationShell::Path::DerivedFrom));
-}
-
-void AssetAdministrationShell::setDerivedFrom(std::shared_ptr<submodel::IReference> derived_from) const
-{
-  this->map.insertKey(IAssetAdministrationShell::Path::DerivedFrom, Reference(*derived_from).getMap());
-}
-
-}
-}
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/src/aas/aas/map/modelurn/ModelUrn.cpp b/sdks/c++/basys.sdk.cc/src/aas/aas/map/modelurn/ModelUrn.cpp
deleted file mode 100644
index 5f25390..0000000
--- a/sdks/c++/basys.sdk.cc/src/aas/aas/map/modelurn/ModelUrn.cpp
+++ /dev/null
@@ -1,7 +0,0 @@
-/*
- * ModelUrn.cpp
- *
- *      Author: wendel
- */
-
-#include "BaSyx/aas/map/modelurn/ModelUrn.h"
diff --git a/sdks/c++/basys.sdk.cc/src/aas/aas/map/parts/Asset.cpp b/sdks/c++/basys.sdk.cc/src/aas/aas/map/parts/Asset.cpp
deleted file mode 100644
index 781e469..0000000
--- a/sdks/c++/basys.sdk.cc/src/aas/aas/map/parts/Asset.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Asset.cpp
- *
- *      Author: wendel
- */
-
-#include <BaSyx/aas/map/parts/Asset.h>
-
-#include <BaSyx/submodel/map/reference/Reference.h>
-
-namespace basyx {
-namespace aas {
-
-using namespace submodel;
-
-Asset::Asset()
-  : ModelType(IAsset::Path::ModelType)
-{}
-
-Asset::Asset(const std::shared_ptr<submodel::IReference> & submodel)
-  : ModelType(IAsset::Path::ModelType)
-{
-  this->setAssetIdentificationModel(submodel);
-}
-
-std::shared_ptr<submodel::IReference> Asset::getAssetIdentificationModel() const
-{
-  return std::make_shared<Reference>(this->map.getProperty(IAsset::Path::AssetIdentificationModel));
-}
-
-std::shared_ptr<submodel::IReference> Asset::getBillOfMaterial() const
-{
-  return std::make_shared<Reference>(this->map.getProperty(IAsset::Path::BillOfMaterial));
-}
-
-
-void Asset::setAssetIdentificationModel(const std::shared_ptr<submodel::IReference>& submodel)
-{
-  this->map.insertKey(IAsset::Path::AssetIdentificationModel, submodel::Reference(*submodel).getMap());
-}
-
-void Asset::setBillOfMaterial(const std::shared_ptr<submodel::IReference>& submodel)
-{
-  this->map.insertKey(IAsset::Path::BillOfMaterial, submodel::Reference(*submodel).getMap());
-}
-
-}
-}
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/src/aas/aas/map/parts/ConceptDictionary.cpp b/sdks/c++/basys.sdk.cc/src/aas/aas/map/parts/ConceptDictionary.cpp
deleted file mode 100644
index 9d8b861..0000000
--- a/sdks/c++/basys.sdk.cc/src/aas/aas/map/parts/ConceptDictionary.cpp
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * ConceptDictionary.cpp
- *
- *      Author: wendel
- */
-
-#include <BaSyx/aas/map/parts/ConceptDictionary.h>
-
-#include <BaSyx/submodel/map/reference/Reference.h>
-
-using namespace basyx::submodel;
-
-namespace basyx {
-namespace aas {
-
-ConceptDictionary::ConceptDictionary(basyx::object obj)
-  : vab::ElementMap(obj)
-{}
-
-ConceptDictionary::ConceptDictionary(basyx::specificCollection_t<submodel::IReference> concept_descriptions)
-  : vab::ElementMap()
-{
-  this->setConceptDescription(concept_descriptions);
-}
-
-basyx::specificCollection_t<submodel::IReference> ConceptDictionary::getConceptDescription() const
-{
-  auto description_objects = this->map.getProperty(IConceptDictionary::Path::ConceptDescriptions).Get<basyx::object::object_list_t>();
-  return vab::ElementMap::make_specific_collection<IReference, Reference>(description_objects);
-}
-
-void ConceptDictionary::setConceptDescription(const basyx::specificCollection_t<submodel::IReference>& references)
-{
-  auto description_objects = vab::ElementMap::make_object_list<IReference, Reference>(references);
-  this->map.insertKey(IConceptDictionary::Path::ConceptDescriptions, description_objects);
-}
-
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/aas/aas/map/parts/View.cpp b/sdks/c++/basys.sdk.cc/src/aas/aas/map/parts/View.cpp
deleted file mode 100644
index 9f652a7..0000000
--- a/sdks/c++/basys.sdk.cc/src/aas/aas/map/parts/View.cpp
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * View.cpp
- *
- *      Author: wendel
- */
-
-#include <BaSyx/aas/map/parts/View.h>
-
-#include <BaSyx/submodel/map/reference/Reference.h>
-
-using namespace basyx::submodel;
-
-namespace basyx {
-namespace aas {
-
-View::View(basyx::object obj)
-  : vab::ElementMap(obj)
-{}
-
-View::View()
-  : vab::ElementMap()
-  , ModelType(IView::Path::ModelType)
-{}
-
-View::View(const basyx::specificCollection_t<submodel::IReference>& references)
-  : vab::ElementMap()
-  , ModelType(IView::Path::ModelType)
-{
-  this->setContainedElements(references);
-}
-
-void View::setContainedElements(const basyx::specificCollection_t<submodel::IReference>& references)
-{
-  auto description_objects = vab::ElementMap::make_object_list<IReference, Reference>(references);
-  this->map.insertKey(IView::Path::ContainedElement, description_objects);
-}
-
-basyx::specificCollection_t<submodel::IReference> View::getContainedElements() const
-{
-  auto description_objects = this->map.getProperty(IView::Path::ContainedElement).Get<basyx::object::object_list_t>();
-  return vab::ElementMap::make_specific_collection<IReference, Reference>(description_objects);
-}
-
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/aas/aas/map/security/Security.cpp b/sdks/c++/basys.sdk.cc/src/aas/aas/map/security/Security.cpp
deleted file mode 100644
index 590fd8a..0000000
--- a/sdks/c++/basys.sdk.cc/src/aas/aas/map/security/Security.cpp
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Security.cpp
- *
- *      Author: wendel
- */
-
-#include "BaSyx/aas/map/security/Security.h"
-
-namespace basyx {
-namespace aas {
-
-Security::Security(ISecurity & other)
-  : vab::ElementMap()
-{}
-
-Security::Security(basyx::object obj)
-  : vab::ElementMap(obj)
-{}
-
-basyx::object Security::getAccessControlPolicyPoints() const
-{
-  return this->map.getProperty(ISecurity::Path::AccessControlPolicyPoints);
-}
-
-basyx::object Security::getTrustAnchor() const
-{
-  return this->map.getProperty(ISecurity::Path::TrustAnchor);
-}
-
-void Security::setAccessControlPolicyPoints(const basyx::object & obj)
-{
-  this->map.insertKey(ISecurity::Path::AccessControlPolicyPoints, obj);
-}
-
-void Security::setTrustAnchor(const basyx::object & obj)
-{
-  this->map.insertKey(ISecurity::Path::TrustAnchor, obj);
-}
-
-}
-}
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/src/abstraction/CMakeLists.txt b/sdks/c++/basys.sdk.cc/src/abstraction/CMakeLists.txt
index 2b733ab..921ffbf 100644
--- a/sdks/c++/basys.sdk.cc/src/abstraction/CMakeLists.txt
+++ b/sdks/c++/basys.sdk.cc/src/abstraction/CMakeLists.txt
@@ -16,7 +16,10 @@
 set_target_properties(${BASYX_ABSTRACTION_LIB_SUFFIX} PROPERTIES PREFIX "${CMAKE_STATIC_LIBRARY_PREFIX}${PROJECT_SHORTNAME}")
 target_include_directories(${BASYX_ABSTRACTION_LIB_SUFFIX}
 INTERFACE ${CMAKE_INSTALL_PREFIX}/include
-       ${CMAKE_INSTALL_PREFIX}/include/${PROJECT_SHORTNAME})
+	PUBLIC 
+	    $<BUILD_INTERFACE:${BASYX_INCLUDE_DIR}>  
+		$<INSTALL_INTERFACE:${CMAKE_INSTALL_PREFIX}/include>
+)
 
 ## basyx::thread sources ##
 
@@ -91,7 +94,15 @@
 add_library(basyx::abstraction ALIAS ${BASYX_ABSTRACTION_LIB_SUFFIX})
 add_library(${PROJECT_SHORTNAME}::${BASYX_ABSTRACTION_LIB_SUFFIX} ALIAS ${BASYX_ABSTRACTION_LIB_SUFFIX})
 
-diagnostics_print(${BASYX_ABSTRACTION_LIB_SUFFIX})
+if(BASYX_IS_SUBMODULE)
+	set_target_properties(${BASYX_ABSTRACTION_LIB_SUFFIX} PROPERTIES FOLDER BaSyx)
+endif()
+
+if(BASYX_VERBOSE_CMAKE_OUTPUT)
+	diagnostics_print(${BASYX_ABSTRACTION_LIB_SUFFIX})
+endif()
+
+build_source_group(${BASYX_ABSTRACTION_LIB_SUFFIX})
 
 ###############################################
 ###           Install section               ###
diff --git a/sdks/c++/basys.sdk.cc/src/controlcomponent/CMakeLists.txt b/sdks/c++/basys.sdk.cc/src/controlcomponent/CMakeLists.txt
new file mode 100644
index 0000000..ec7be80
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/src/controlcomponent/CMakeLists.txt
@@ -0,0 +1,70 @@
+######################################################
+###              BaSyx::ControlComponent           ###
+######################################################
+
+include(CMakePackageConfigHelpers)
+
+set (BASYX_CONTROLCOMPONENT_LIB_SUFFIX "Controlcomponent")
+
+set (BASYX_CONTROLCOMPONENT_LIBRARY_NAME "${PROJECT_SHORTNAME}${BASYX_CONTROLCOMPONENT_LIB_SUFFIX}")
+
+set (BASYX_CONTROLCOMPONENT_INCLUDE_DIR "${BASYX_INCLUDE_DIR}/BaSyx/controlcomponent")
+set (PROJECT_INCLUDE_DIR BASYX_CONTROLCOMPONENT_INCLUDE_DIR)
+
+add_library(${BASYX_CONTROLCOMPONENT_LIB_SUFFIX})
+
+set_target_properties(${BASYX_CONTROLCOMPONENT_LIB_SUFFIX} PROPERTIES VERSION ${PROJECT_VERSION})
+set_target_properties(${BASYX_CONTROLCOMPONENT_LIB_SUFFIX} PROPERTIES SOVERSION ${BASYX_PACKAGE_VERSION_MAJOR})
+set_target_properties(${BASYX_CONTROLCOMPONENT_LIB_SUFFIX} PROPERTIES PREFIX "${CMAKE_STATIC_LIBRARY_PREFIX}${PROJECT_SHORTNAME}")
+set_target_properties(${BASYX_CONTROLCOMPONENT_LIB_SUFFIX} PROPERTIES LINKER_LANGUAGE CXX)
+
+target_include_directories(${BASYX_CONTROLCOMPONENT_LIB_SUFFIX}
+	PUBLIC 
+	    $<BUILD_INTERFACE:${BASYX_INCLUDE_DIR}>  
+		$<INSTALL_INTERFACE:${CMAKE_INSTALL_PREFIX}/include>
+)
+
+
+
+#Implementation files
+target_sources(${BASYX_CONTROLCOMPONENT_LIB_SUFFIX}
+    PRIVATE
+        ${CMAKE_CURRENT_SOURCE_DIR}/enumerations/ControlComponentConstants.cpp
+        ${CMAKE_CURRENT_SOURCE_DIR}/enumerations/ExecutionOrder.cpp
+        ${CMAKE_CURRENT_SOURCE_DIR}/enumerations/ExecutionState.cpp
+
+        ${CMAKE_CURRENT_SOURCE_DIR}/map/ControlComponent.cpp
+        ${CMAKE_CURRENT_SOURCE_DIR}/simple/ControlComponent.cpp
+)
+
+#Header files
+target_sources(${BASYX_CONTROLCOMPONENT_LIB_SUFFIX}
+    PRIVATE
+        ${BASYX_CONTROLCOMPONENT_INCLUDE_DIR}/interfaces/IControlComponentChangeListener.h
+        ${BASYX_CONTROLCOMPONENT_INCLUDE_DIR}/interfaces/IControlComponent.h
+
+        ${BASYX_CONTROLCOMPONENT_INCLUDE_DIR}/enumerations/ControlComponentConstants.h
+        ${BASYX_CONTROLCOMPONENT_INCLUDE_DIR}/enumerations/ExecutionMode.h
+        ${BASYX_CONTROLCOMPONENT_INCLUDE_DIR}/enumerations/ExecutionOrder.h
+        ${BASYX_CONTROLCOMPONENT_INCLUDE_DIR}/enumerations/ExecutionState.h
+        ${BASYX_CONTROLCOMPONENT_INCLUDE_DIR}/enumerations/OccupationState.h
+
+        ${BASYX_CONTROLCOMPONENT_INCLUDE_DIR}/map/ControlComponent.h
+        ${BASYX_CONTROLCOMPONENT_INCLUDE_DIR}/simple/ControlComponent.h
+        )
+
+add_library(basyx::controlcomponent ALIAS ${BASYX_CONTROLCOMPONENT_LIB_SUFFIX})
+add_library(${PROJECT_SHORTNAME}::${BASYX_CONTROLCOMPONENT_LIB_SUFFIX} ALIAS ${BASYX_CONTROLCOMPONENT_LIB_SUFFIX})
+
+target_include_directories(${BASYX_CONTROLCOMPONENT_LIB_SUFFIX} PRIVATE ${PROJECT_SOURCE_DIR})
+target_link_libraries(${BASYX_CONTROLCOMPONENT_LIB_SUFFIX}
+        PUBLIC
+        BaSyx::Shared
+        BaSyx::VAB
+)
+
+if(BASYX_IS_SUBMODULE)
+	set_target_properties(${BASYX_CONTROLCOMPONENT_LIB_SUFFIX} PROPERTIES FOLDER BaSyx)
+endif()
+
+build_source_group(${BASYX_CONTROLCOMPONENT_LIB_SUFFIX})
diff --git a/sdks/c++/basys.sdk.cc/src/controlcomponent/enumerations/ControlComponentConstants.cpp b/sdks/c++/basys.sdk.cc/src/controlcomponent/enumerations/ControlComponentConstants.cpp
new file mode 100644
index 0000000..4703f6c
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/src/controlcomponent/enumerations/ControlComponentConstants.cpp
@@ -0,0 +1,69 @@
+#include <BaSyx/controlcomponent/enumerations/ControlComponentConstants.h>
+
+#include <array>
+#include <algorithm>
+#include <memory>
+#include <string>
+
+using namespace basyx::controlcomponent;
+
+using enum_pair_t = std::pair<const char*, ControlComponentConstants>;
+
+static const std::array<enum_pair_t, 34> string_to_enum = 
+{
+    std::make_pair("status",  ControlComponentConstants::status),
+    std::make_pair("orderList", ControlComponentConstants::orderList),
+    std::make_pair("LOCAL", ControlComponentConstants::LOCAL),
+    std::make_pair("operations", ControlComponentConstants::operations),
+    std::make_pair("service", ControlComponentConstants::service),
+    std::make_pair("clear", ControlComponentConstants::clear),
+    std::make_pair("stop", ControlComponentConstants::stop),
+    std::make_pair("abort", ControlComponentConstants::abort),
+    std::make_pair("unsuspend", ControlComponentConstants::unsuspend),
+    std::make_pair("suspend", ControlComponentConstants::suspend),
+    std::make_pair("unhold", ControlComponentConstants::unhold),
+    std::make_pair("hold", ControlComponentConstants::hold),
+    std::make_pair("reset", ControlComponentConstants::reset),
+    std::make_pair("start", ControlComponentConstants::start),
+    std::make_pair("simulation", ControlComponentConstants::simulation),
+    std::make_pair("manual", ControlComponentConstants::manual),
+    std::make_pair("auto", ControlComponentConstants::Auto),
+    std::make_pair("semiauto", ControlComponentConstants::semiauto),
+    std::make_pair("priority", ControlComponentConstants::priority),
+    std::make_pair("occupy", ControlComponentConstants::occupy),
+    std::make_pair("free", ControlComponentConstants::free),
+    std::make_pair("bstate", ControlComponentConstants::bstate),
+    std::make_pair("cmd", ControlComponentConstants::cmd),
+    std::make_pair("localOverwriteFree", ControlComponentConstants::localOverwriteFree),
+    std::make_pair("localOverwrite", ControlComponentConstants::localOverwrite),
+    std::make_pair("prevError", ControlComponentConstants::prevError),
+    std::make_pair("errorState", ControlComponentConstants::errorState),
+    std::make_pair("workState", ControlComponentConstants::workState),
+    std::make_pair("opMode", ControlComponentConstants::opMode),
+    std::make_pair("exState", ControlComponentConstants::exState),
+    std::make_pair("exMode", ControlComponentConstants::exMode),
+    std::make_pair("lastOccupier", ControlComponentConstants::lastOccupier),
+    std::make_pair("occupier", ControlComponentConstants::occupier),
+    std::make_pair("occupationState", ControlComponentConstants::occupationState),
+};
+
+ControlComponentConstants ControlComponentConstants_::from_string(const std::string & name)
+{
+    auto pair = std::find_if(string_to_enum.begin(), string_to_enum.end(), 
+		[&name](const enum_pair_t & pair) {
+			return !name.compare(pair.first);
+	});
+
+    return pair->second;
+}
+
+const char * ControlComponentConstants_::to_string(ControlComponentConstants value)
+{
+    auto pair = std::find_if(string_to_enum.begin(), string_to_enum.end(), 
+		[value](const enum_pair_t & pair) {
+			return value == pair.second;
+	});
+
+    return pair->first;
+}
+
diff --git a/sdks/c++/basys.sdk.cc/src/controlcomponent/enumerations/ExecutionOrder.cpp b/sdks/c++/basys.sdk.cc/src/controlcomponent/enumerations/ExecutionOrder.cpp
new file mode 100644
index 0000000..3b70e04
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/src/controlcomponent/enumerations/ExecutionOrder.cpp
@@ -0,0 +1,45 @@
+#include <BaSyx/controlcomponent/enumerations/ExecutionOrder.h>
+
+#include <array>
+#include <algorithm>
+#include <memory>
+#include <string>
+
+using namespace basyx::controlcomponent;
+
+using enum_pair_t = std::pair<const char*, ExecutionOrder>;
+
+static const std::array<enum_pair_t, 10> string_to_enum = 
+{
+    std::make_pair("start",  ExecutionOrder::start),
+    std::make_pair("complete", ExecutionOrder::complete),
+    std::make_pair("reset", ExecutionOrder::reset),
+    std::make_pair("hold", ExecutionOrder::hold),
+    std::make_pair("unhold", ExecutionOrder::unhold),
+    std::make_pair("suspend", ExecutionOrder::suspend),
+    std::make_pair("unsuspend", ExecutionOrder::unsuspend),
+    std::make_pair("clear", ExecutionOrder::clear),
+    std::make_pair("stop", ExecutionOrder::stop),
+    std::make_pair("abort", ExecutionOrder::abort),
+};
+
+ExecutionOrder ExecutionOrder_::from_string(const std::string & name)
+{
+    auto pair = std::find_if(string_to_enum.begin(), string_to_enum.end(), 
+		[&name](const enum_pair_t & pair) {
+			return !name.compare(pair.first);
+	});
+
+    return pair->second;
+}
+
+const char * ExecutionOrder_::to_string(ExecutionOrder value)
+{
+    auto pair = std::find_if(string_to_enum.begin(), string_to_enum.end(), 
+		[value](const enum_pair_t & pair) {
+			return value == pair.second;
+	});
+
+    return pair->first;
+}
+
diff --git a/sdks/c++/basys.sdk.cc/src/controlcomponent/enumerations/ExecutionState.cpp b/sdks/c++/basys.sdk.cc/src/controlcomponent/enumerations/ExecutionState.cpp
new file mode 100644
index 0000000..7c97d75
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/src/controlcomponent/enumerations/ExecutionState.cpp
@@ -0,0 +1,52 @@
+#include <BaSyx/controlcomponent/enumerations/ExecutionState.h>
+
+#include <array>
+#include <algorithm>
+#include <memory>
+#include <string>
+
+using namespace basyx::controlcomponent;
+
+using enum_pair_t = std::pair<const char*, ExecutionState>;
+
+static const std::array<enum_pair_t, 17> string_to_enum = 
+{
+    std::make_pair("idle",  ExecutionState::idle),
+    std::make_pair("starting", ExecutionState::starting),
+    std::make_pair("execute", ExecutionState::execute),
+    std::make_pair("completing", ExecutionState::completing),
+    std::make_pair("complete", ExecutionState::complete),
+    std::make_pair("resetting", ExecutionState::resetting),
+    std::make_pair("holding", ExecutionState::holding),
+    std::make_pair("held", ExecutionState::held),
+    std::make_pair("unholding", ExecutionState::unholding),
+    std::make_pair("suspending", ExecutionState::suspending),
+    std::make_pair("suspended", ExecutionState::suspended),
+    std::make_pair("unsuspending", ExecutionState::unsuspending),
+    std::make_pair("stopping", ExecutionState::stopping),
+    std::make_pair("stopped", ExecutionState::stopped),
+    std::make_pair("aborting", ExecutionState::aborting),
+    std::make_pair("aborted", ExecutionState::aborted),
+    std::make_pair("clearing", ExecutionState::clearing),
+};
+
+ExecutionState ExecutionState_::from_string(const std::string & name)
+{
+    auto pair = std::find_if(string_to_enum.begin(), string_to_enum.end(), 
+		[&name](const enum_pair_t & pair) {
+			return !name.compare(pair.first);
+	});
+
+    return pair->second;
+}
+
+const char * ExecutionState_::to_string(ExecutionState value)
+{
+    auto pair = std::find_if(string_to_enum.begin(), string_to_enum.end(), 
+		[value](const enum_pair_t & pair) {
+			return value == pair.second;
+	});
+
+    return pair->first;
+}
+
diff --git a/sdks/c++/basys.sdk.cc/src/controlcomponent/map/ControlComponent.cpp b/sdks/c++/basys.sdk.cc/src/controlcomponent/map/ControlComponent.cpp
new file mode 100644
index 0000000..f8f431a
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/src/controlcomponent/map/ControlComponent.cpp
@@ -0,0 +1,703 @@
+#include <BaSyx/controlcomponent/map/ControlComponent.h>
+#include <BaSyx/controlcomponent/enumerations/ControlComponentConstants.h>
+
+namespace basyx {
+namespace controlcomponent {
+namespace map {
+
+using constants = basyx::controlcomponent::ControlComponentConstants;
+using constants_ = basyx::controlcomponent::ControlComponentConstants_;
+
+ControlComponent::ControlComponent()
+  : vab::ElementMap {}, savedOccupierId {""}, status_map {object::make_map()}, operations {object::make_map()}
+{
+  this->map.insertKey(constants_::to_string(constants::orderList), std::vector<std::string>{});
+
+  //initialize status map
+  this->map.insertKey(constants_::to_string(constants::status), this->status_map);
+  this->insert_status(constants::occupationState, (int) OccupationState::free);
+  this->insert_status(constants::occupier, "");
+  this->insert_status(constants::lastOccupier, "");
+  this->insert_status(constants::exMode, (int) ExecutionMode::Auto);
+  this->insert_status(constants::exState, ExecutionState_::to_string(ExecutionState::idle));
+  this->insert_status(constants::opMode, "");
+  this->insert_status(constants::workState, "");
+  this->insert_status(constants::errorState, "");
+  this->insert_status(constants::prevError, "");
+
+  //initialize input signals
+  this->map.insertKey(constants_::to_string(constants::cmd), "");
+  this->map.insertKey(constants_::to_string(constants::localOverwrite), "");
+  this->map.insertKey(constants_::to_string(constants::localOverwriteFree), "");
+
+  // Add operations map
+  this->map.insertKey(constants_::to_string(constants::operations), this->operations);
+  this->operations.insertKey(constants_::to_string(constants::service), init_service_operations());
+}
+
+void ControlComponent::addControlComponentChangeListener(const std::shared_ptr<IControlComponentChangeListener> listener)
+{
+  this->componentChangeListeners.emplace(listener->getUniqueID(), listener);
+}
+
+void ControlComponent::removeControlComponentChangeListener(const std::shared_ptr<IControlComponentChangeListener> listener)
+{
+  this->componentChangeListeners.erase(listener->getUniqueID());
+}
+
+const basyx::object ControlComponent::getServiceOperationMap()
+{
+  return this->map.getProperty(constants_::to_string(constants::operations)).getProperty(constants_::to_string(constants::service));
+}
+
+void ControlComponent::put(const std::string &key, object value)
+{
+  this->map.insertKey(key, value);
+
+  // Indicate value change
+  for (auto listener : componentChangeListeners)
+  {
+    listener.second->onVariableChange(key, value);
+  }
+
+  // Process variable changes
+  switch (constants_::from_string(key))
+  {
+    case constants::cmd:
+    {
+      this->changeExecutionState(ExecutionOrder_::from_string(value.Get<std::string>()));
+      break;
+    }
+    case constants::localOverwrite:
+    {
+      this->invokeLocalOverwrite();
+      break;
+    }
+    case constants::localOverwriteFree:
+    {
+      this->clearLocalOverwrite();
+      break;
+    }
+  }
+}
+
+void ControlComponent::finishState()
+{
+  switch (this->getExecutionState())
+  {
+    case ExecutionState::starting:
+    {
+      this->setExecutionState(ExecutionState::execute);
+      return;
+    }
+    case ExecutionState::execute:
+    {
+      this->setExecutionState(ExecutionState::completing);
+      return;
+    }
+    case ExecutionState::completing:
+    {
+      this->setExecutionState(ExecutionState::complete);
+      return;
+    }
+    case ExecutionState::resetting:
+    {
+      this->setExecutionState(ExecutionState::idle);
+      return;
+    }
+    case ExecutionState::holding:
+    {
+      this->setExecutionState(ExecutionState::held);
+      return;
+    }
+    case ExecutionState::unholding:
+    {
+      this->setExecutionState(ExecutionState::execute);
+      return;
+    }
+    case ExecutionState::suspending:
+    {
+      this->setExecutionState(ExecutionState::suspended);
+      return;
+    }
+    case ExecutionState::unsuspending:
+    {
+      this->setExecutionState(ExecutionState::execute);
+      return;
+    }
+    case ExecutionState::stopping:
+    {
+      this->setExecutionState(ExecutionState::stopped);
+      return;
+    }
+    case ExecutionState::stopped:
+    {
+      this->setExecutionState(ExecutionState::idle);
+      return;
+    }
+    case ExecutionState::aborting:
+    {
+      this->setExecutionState(ExecutionState::aborted);
+      return;
+    }
+    case ExecutionState::clearing:
+    {
+      this->setExecutionState(ExecutionState::stopped);
+      return;
+    }
+  }
+}
+
+const std::vector<std::string> & ControlComponent::getOrderList()
+{
+  return *this->map.getProperty(constants_::to_string(constants::orderList)).GetPtr<std::vector<std::string>>();
+}
+
+void ControlComponent::addOrder(const std::string &newOrder)
+{
+  this->map.getProperty(constants_::to_string(constants::orderList)).GetPtr<std::vector<std::string>>()->push_back(newOrder);
+}
+
+void ControlComponent::clearOrder()
+{
+  this->map.getProperty(constants_::to_string(constants::orderList)).GetPtr<object::list_t<std::string>>()->clear();
+}
+
+OccupationState ControlComponent::getOccupationState()
+{
+  return static_cast<OccupationState>(this->status_map.getProperty(constants_::to_string(constants::occupationState)).Get<int>());
+}
+
+void ControlComponent::setOccupationState(const OccupationState &occState)
+{
+  this->insert_status(constants::occupationState, (int) occState);
+
+  for (auto listener : this->componentChangeListeners)
+  {
+    listener.second->onNewOccupationState(occState);
+  }
+}
+
+std::string ControlComponent::getOccupierID()
+{
+  return this->get_status<std::string>(constants::occupier);
+}
+
+void ControlComponent::setOccupierID(const std::string &occId)
+{
+  this->insert_status(constants::occupier, occId);
+
+  for (auto listener : this->componentChangeListeners)
+  {
+    listener.second->onNewOccupier(occId);
+  }
+}
+
+std::string ControlComponent::getLastOccupierID()
+{
+  return this->get_status<std::string>(constants::lastOccupier);
+}
+
+void ControlComponent::setLastOccupierID(const std::string &occId)
+{
+  this->insert_status(constants::lastOccupier, occId);
+
+  for (auto listener : this->componentChangeListeners)
+  {
+    listener.second->onLastOccupier(occId);
+  }
+}
+
+ExecutionMode ControlComponent::getExecutionMode()
+{
+  return (ExecutionMode) this->get_status<int>(constants::exMode);
+}
+
+void ControlComponent::setExecutionMode(const ExecutionMode &exMode)
+{
+  this->insert_status(constants::exMode, (int) exMode);
+
+  for (auto listener : this->componentChangeListeners)
+  {
+    listener.second->onChangedExecutionMode(exMode);
+  }
+}
+
+ExecutionState ControlComponent::getExecutionState()
+{
+  return ExecutionState_::from_string(this->get_status<std::string>(constants::exState));
+}
+
+void ControlComponent::setExecutionState(const ExecutionState &newSt)
+{
+  this->insert_status(constants::exState, ExecutionState_::to_string(newSt));
+
+  for (auto listener : this->componentChangeListeners)
+  {
+    listener.second->onChangedExecutionState(newSt);
+  }
+}
+
+std::string ControlComponent::getOperationMode()
+{
+  return this->get_status<std::string>(constants::opMode);
+}
+
+void ControlComponent::setOperationMode(const std::string &opMode)
+{
+  this->insert_status(constants::opMode, opMode);
+
+  for (auto listener : this->componentChangeListeners)
+  {
+    listener.second->onChangedOperationMode(opMode);
+  }
+}
+
+std::string ControlComponent::getWorkState()
+{
+  return this->get_status<std::string>(constants::workState);
+}
+
+void ControlComponent::setWorkState(const std::string &workState)
+{
+  this->insert_status(constants::workState, workState);
+
+  for (auto listener : this->componentChangeListeners)
+  {
+    listener.second->onChangedWorkState(workState);
+  }
+}
+
+std::string ControlComponent::getErrorState()
+{
+  return this->get_status<std::string>(constants::errorState);
+}
+
+void ControlComponent::setErrorState(const std::string &errorState)
+{
+  this->insert_status(constants::errorState, errorState);
+
+  for (auto listener : this->componentChangeListeners)
+  {
+    listener.second->onChangedErrorState(errorState);
+  }
+}
+
+std::string ControlComponent::getLastErrorState()
+{
+  return this->get_status<std::string>(constants::prevError);
+}
+
+void ControlComponent::setLastErrorState(const std::string &lastErrorState)
+{
+  this->insert_status(constants::errorState, lastErrorState);
+
+  for (auto listener : this->componentChangeListeners)
+  {
+    listener.second->onChangedPrevError(lastErrorState);
+  }
+}
+
+std::string ControlComponent::getCommand()
+{
+  return this->map.getProperty(constants_::to_string(constants::cmd)).GetStringContent();
+}
+
+void ControlComponent::setCommand(const std::string &cmd)
+{
+  this->map.insertKey(constants_::to_string(constants::cmd), cmd);
+}
+
+std::string ControlComponent::getLocalOverwrite()
+{
+  return this->map.getProperty(constants_::to_string(constants::localOverwrite)).GetStringContent();
+}
+
+void ControlComponent::setLocalOverwrite(const std::string &cmd)
+{
+  this->map.insertKey(constants_::to_string(constants::localOverwrite), cmd);
+}
+
+std::string ControlComponent::getLocalOverwriteFree()
+{
+  return this->map.getProperty(constants_::to_string(constants::localOverwriteFree)).GetStringContent();
+}
+
+void ControlComponent::setLocalOverwriteFree(const std::string &cmd)
+{
+  this->map.insertKey(constants_::to_string(constants::localOverwriteFree), cmd);
+}
+
+void ControlComponent::changeExecutionState(const ExecutionOrder &ex_order)
+{
+  // Check if execution order leads to valid state in current state
+  switch (this->getExecutionState())
+  {
+    case ExecutionState::idle:
+      // Process expected orders
+      if (ex_order == ExecutionOrder::start)
+      {
+        this->setExecutionState(ExecutionState::starting);
+        return;
+      }
+      if (ex_order == ExecutionOrder::stop)
+      {
+        this->setExecutionState(ExecutionState::stopping);
+        return;
+      }
+      if (ex_order == ExecutionOrder::abort)
+      {
+        this->setExecutionState(ExecutionState::aborting);
+        return;
+      }
+
+    case ExecutionState::starting:
+      if (ex_order == ExecutionOrder::stop)
+      {
+        this->setExecutionState(ExecutionState::stopping);
+        return;
+      }
+      if (ex_order == ExecutionOrder::abort)
+      {
+        this->setExecutionState(ExecutionState::aborting);
+        return;
+      }
+
+    case ExecutionState::execute:
+      // Process expected orders
+      if (ex_order == ExecutionOrder::complete)
+      {
+        this->setExecutionState(ExecutionState::completing);
+        return;
+      }
+      if (ex_order == ExecutionOrder::hold)
+      {
+        this->setExecutionState(ExecutionState::holding);
+        return;
+      }
+      if (ex_order == ExecutionOrder::suspend)
+      {
+        this->setExecutionState(ExecutionState::suspending);
+        return;
+      }
+      if (ex_order == ExecutionOrder::stop)
+      {
+        this->setExecutionState(ExecutionState::stopping);
+        return;
+      }
+      if (ex_order == ExecutionOrder::abort)
+      {
+        this->setExecutionState(ExecutionState::aborting);
+        return;
+      }
+
+    case ExecutionState::completing:
+      if (ex_order == ExecutionOrder::stop)
+      {
+        this->setExecutionState(ExecutionState::stopping);
+        return;
+      }
+      if (ex_order == ExecutionOrder::abort)
+      {
+        this->setExecutionState(ExecutionState::aborting);
+        return;
+      }
+
+    case ExecutionState::complete:
+      if (ex_order == ExecutionOrder::reset)
+      {
+        this->setExecutionState(ExecutionState::resetting);
+        return;
+      }
+      if (ex_order == ExecutionOrder::stop)
+      {
+        this->setExecutionState(ExecutionState::stopping);
+        return;
+      }
+      if (ex_order == ExecutionOrder::abort)
+      {
+        this->setExecutionState(ExecutionState::aborting);
+        return;
+      }
+
+    case ExecutionState::resetting:
+      if (ex_order == ExecutionOrder::stop)
+      {
+        this->setExecutionState(ExecutionState::stopping);
+        return;
+      }
+      if (ex_order == ExecutionOrder::abort)
+      {
+        this->setExecutionState(ExecutionState::aborting);
+        return;
+      }
+
+    case ExecutionState::holding:
+      if (ex_order == ExecutionOrder::stop)
+      {
+        this->setExecutionState(ExecutionState::stopping);
+        return;
+      }
+      if (ex_order == ExecutionOrder::abort)
+      {
+        this->setExecutionState(ExecutionState::aborting);
+        return;
+      }
+
+    case ExecutionState::held:
+      if (ex_order == ExecutionOrder::unhold)
+      {
+        this->setExecutionState(ExecutionState::unholding);
+        return;
+      }
+      if (ex_order == ExecutionOrder::stop)
+      {
+        this->setExecutionState(ExecutionState::stopping);
+        return;
+      }
+      if (ex_order == ExecutionOrder::abort)
+      {
+        this->setExecutionState(ExecutionState::aborting);
+        return;
+      }
+
+    case ExecutionState::unholding:
+      if (ex_order == ExecutionOrder::stop)
+      {
+        this->setExecutionState(ExecutionState::stopping);
+        return;
+      }
+      if (ex_order == ExecutionOrder::abort)
+      {
+        this->setExecutionState(ExecutionState::aborting);
+        return;
+      }
+
+    case ExecutionState::suspending:
+      if (ex_order == ExecutionOrder::stop)
+      {
+        this->setExecutionState(ExecutionState::stopping);
+        return;
+      }
+      if (ex_order == ExecutionOrder::abort)
+      {
+        this->setExecutionState(ExecutionState::aborting);
+        return;
+      }
+
+    case ExecutionState::suspended:
+      if (ex_order == ExecutionOrder::unsuspend)
+      {
+        this->setExecutionState(ExecutionState::unsuspending);
+        return;
+      }
+      if (ex_order == ExecutionOrder::stop)
+      {
+        this->setExecutionState(ExecutionState::stopping);
+        return;
+      }
+      if (ex_order == ExecutionOrder::abort)
+      {
+        this->setExecutionState(ExecutionState::aborting);
+        return;
+      }
+
+    case ExecutionState::unsuspending:
+      if (ex_order == ExecutionOrder::stop)
+      {
+        this->setExecutionState(ExecutionState::stopping);
+        return;
+      }
+      if (ex_order == ExecutionOrder::abort)
+      {
+        this->setExecutionState(ExecutionState::aborting);
+        return;
+      }
+
+    case ExecutionState::stopping:
+      if (ex_order == ExecutionOrder::abort)
+      {
+        this->setExecutionState(ExecutionState::aborting);
+        return;
+      }
+
+    case ExecutionState::stopped:
+      if (ex_order == ExecutionOrder::reset)
+      {
+        this->setExecutionState(ExecutionState::resetting);
+        return;
+      }
+      if (ex_order == ExecutionOrder::abort)
+      {
+        this->setExecutionState(ExecutionState::aborting);
+        return;
+      }
+    case ExecutionState::aborted:
+      if (ex_order == ExecutionOrder::clear)
+      {
+        this->setExecutionState(ExecutionState::clearing);
+        return;
+      }
+
+    case ExecutionState::clearing:
+      if (ex_order == ExecutionOrder::abort)
+      {
+        this->setExecutionState(ExecutionState::aborting);
+        return;
+      }
+  }
+
+}
+
+void ControlComponent::invokeLocalOverwrite()
+{
+  // Store current occupier because we need to restore it later
+  this->savedOccupierId = this->getOccupierID();
+
+  // Enter local overwrite state
+  this->setOccupationState(OccupationState::local);
+  this->setOccupierID(constants_::to_string(constants::LOCAL));
+}
+
+void ControlComponent::clearLocalOverwrite()
+{
+  this->setOccupierID(this->savedOccupierId);
+
+  // Restore occupier state based on variables
+  if (this->savedOccupierId.empty())
+    this->setOccupationState(OccupationState::free);
+  else if (this->getLastOccupierID().empty())
+    this->setOccupationState(OccupationState::occupied);
+  else
+    this->setOccupationState(OccupationState::priority);
+}
+
+template<typename T> void ControlComponent::insert_status(const ControlComponentConstants &status_key, T status)
+{
+  this->status_map.insertKey(constants_::to_string(status_key), status);
+  for (auto listener : this->componentChangeListeners)
+  {
+    listener.second->onVariableChange(constants_::to_string(status_key), status);
+  }
+}
+
+template<typename T> T ControlComponent::get_status(const basyx::controlcomponent::ControlComponentConstants &key)
+{
+  return this->status_map.getProperty(constants_::to_string(key)).Get<T>();
+}
+
+object ControlComponent::init_service_operations()
+{
+  object map = object::make_map();
+
+  // All lambdas returning bool since this is supported by vab
+  map.insertKey(constants_::to_string(constants::free), object::make_function([this](std::string senderId) {
+    this->freeControlComponent(senderId);
+    return true;
+  }));
+  map.insertKey(constants_::to_string(constants::occupy), object::make_function([this](std::string occupier) {
+    this->occupyControlComponent(occupier);
+    return true;
+  }));
+  map.insertKey(constants_::to_string(constants::priority), object::make_function([this](std::string occupier) {
+    this->priorityOccupation(occupier);
+    return true;
+  }));
+
+  map.insertKey(constants_::to_string(constants::Auto), object::make_function([this]() {
+    this->setExecutionMode(ExecutionMode::Auto);
+    return true;
+  }));
+  map.insertKey(constants_::to_string(constants::semiauto), object::make_function([this]() {
+    this->setExecutionMode(ExecutionMode::Semiauto);
+    return true;
+  }));
+  map.insertKey(constants_::to_string(constants::manual), object::make_function([this]() {
+    this->setExecutionMode(ExecutionMode::Manual);
+    return true;
+  }));
+  map.insertKey(constants_::to_string(constants::simulation), object::make_function([this]() {
+    this->setExecutionMode(ExecutionMode::Simulation);
+    return true;
+  }));
+
+  map.insertKey(constants_::to_string(constants::start), object::make_function([this]() {
+    this->changeExecutionState(ExecutionOrder::start);
+    return true;
+  }));
+  map.insertKey(constants_::to_string(constants::reset), object::make_function([this]() {
+    this->changeExecutionState(ExecutionOrder::reset);
+    return true;
+  }));
+  map.insertKey(constants_::to_string(constants::hold), object::make_function([this]() {
+    this->changeExecutionState(ExecutionOrder::hold);
+    return true;
+  }));
+  map.insertKey(constants_::to_string(constants::unhold), object::make_function([this]() {
+    this->changeExecutionState(ExecutionOrder::unhold);
+    return true;
+  }));
+  map.insertKey(constants_::to_string(constants::suspend), object::make_function([this]() {
+    this->changeExecutionState(ExecutionOrder::suspend);
+    return true;
+  }));
+  map.insertKey(constants_::to_string(constants::unsuspend), object::make_function([this]() {
+    this->changeExecutionState(ExecutionOrder::unsuspend);
+    return true;
+  }));
+  map.insertKey(constants_::to_string(constants::abort), object::make_function([this]() {
+    this->changeExecutionState(ExecutionOrder::abort);
+    return true;
+  }));
+  map.insertKey(constants_::to_string(constants::stop), object::make_function([this]() {
+    this->changeExecutionState(ExecutionOrder::stop);
+    return true;
+  }));
+  map.insertKey(constants_::to_string(constants::clear), object::make_function([this]() {
+    this->changeExecutionState(ExecutionOrder::clear);
+    return true;
+  }));
+
+  map.insertKey(constants_::to_string(constants::bstate), object::make_function([this]() {
+    this->setOperationMode(std::string {"BSTATE"});
+    return true;
+  }));
+
+  return map;
+}
+
+void ControlComponent::freeControlComponent(const std::string &senderId)
+{
+  if (this->getOccupierID().compare(senderId) == 0)
+  {
+    this->setOccupierID(this->getLastOccupierID());
+    this->setLastOccupierID("");
+    if (this->getOccupierID().empty())
+      this->setOccupationState(OccupationState::free);
+    else
+      this->setOccupationState(OccupationState::occupied);
+  }
+}
+
+void ControlComponent::occupyControlComponent(const std::string &occupier)
+{
+  if (this->getOccupationState() == OccupationState::free)
+  {
+    this->setOccupierID(occupier);
+    this->setOccupationState(OccupationState::occupied);
+  }
+}
+
+void ControlComponent::priorityOccupation(const std::string &occupier)
+{
+  if ((this->getOccupationState() == OccupationState::free) or (this->getOccupationState() == OccupationState::occupied))
+  {
+    this->setLastOccupierID(this->getOccupierID());
+    this->setOccupierID(occupier);
+    this->setOccupationState(OccupationState::priority);
+  }
+}
+
+}
+}
+}
diff --git a/sdks/c++/basys.sdk.cc/src/controlcomponent/simple/ControlComponent.cpp b/sdks/c++/basys.sdk.cc/src/controlcomponent/simple/ControlComponent.cpp
new file mode 100644
index 0000000..da523da
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/src/controlcomponent/simple/ControlComponent.cpp
@@ -0,0 +1,663 @@
+#include <BaSyx/controlcomponent/simple/ControlComponent.h>
+#include <BaSyx/controlcomponent/enumerations/ControlComponentConstants.h>
+
+namespace basyx {
+namespace controlcomponent {
+namespace simple {
+
+using constants = basyx::controlcomponent::ControlComponentConstants;
+using constants_ = basyx::controlcomponent::ControlComponentConstants_;
+
+ControlComponent::ControlComponent()
+  : savedOccupierId {""}
+  , occupationState{OccupationState::free}
+  , occupier{""}
+  , lastOccupier{""}
+  , exMode{ExecutionMode::Auto}
+  , exState{ExecutionState::idle}
+  , opMode{""}
+  , workState{""}
+  , errorState{""}
+  , prevError{""}
+  , cmd{""}
+  , localOverwrite{""}
+  , localOverwriteFree{""}
+  , service_operations{object::make_map()}
+{
+  this->init_service_operations();
+}
+
+void ControlComponent::addControlComponentChangeListener(const std::shared_ptr<IControlComponentChangeListener> listener)
+{
+  this->componentChangeListeners.emplace(listener->getUniqueID(), listener);
+}
+
+void ControlComponent::removeControlComponentChangeListener(const std::shared_ptr<IControlComponentChangeListener> listener)
+{
+  this->componentChangeListeners.erase(listener->getUniqueID());
+}
+
+const basyx::object ControlComponent::getServiceOperationMap()
+{
+  return this->service_operations;
+}
+
+void ControlComponent::finishState()
+{
+  switch (this->getExecutionState())
+  {
+    case ExecutionState::starting:
+    {
+      this->setExecutionState(ExecutionState::execute);
+      return;
+    }
+    case ExecutionState::execute:
+    {
+      this->setExecutionState(ExecutionState::completing);
+      return;
+    }
+    case ExecutionState::completing:
+    {
+      this->setExecutionState(ExecutionState::complete);
+      return;
+    }
+    case ExecutionState::resetting:
+    {
+      this->setExecutionState(ExecutionState::idle);
+      return;
+    }
+    case ExecutionState::holding:
+    {
+      this->setExecutionState(ExecutionState::held);
+      return;
+    }
+    case ExecutionState::unholding:
+    {
+      this->setExecutionState(ExecutionState::execute);
+      return;
+    }
+    case ExecutionState::suspending:
+    {
+      this->setExecutionState(ExecutionState::suspended);
+      return;
+    }
+    case ExecutionState::unsuspending:
+    {
+      this->setExecutionState(ExecutionState::execute);
+      return;
+    }
+    case ExecutionState::stopping:
+    {
+      this->setExecutionState(ExecutionState::stopped);
+      return;
+    }
+    case ExecutionState::stopped:
+    {
+      this->setExecutionState(ExecutionState::idle);
+      return;
+    }
+    case ExecutionState::aborting:
+    {
+      this->setExecutionState(ExecutionState::aborted);
+      return;
+    }
+    case ExecutionState::clearing:
+    {
+      this->setExecutionState(ExecutionState::stopped);
+      return;
+    }
+  }
+}
+
+const std::vector<std::string> & ControlComponent::getOrderList()
+{
+  return this->orderList;
+}
+
+void ControlComponent::addOrder(const std::string &newOrder)
+{
+  this->orderList.push_back(newOrder);
+}
+
+void ControlComponent::clearOrder()
+{
+  this->orderList.clear();
+}
+
+OccupationState ControlComponent::getOccupationState()
+{
+  return static_cast<OccupationState>(this->occupationState);
+}
+
+void ControlComponent::setOccupationState(const OccupationState &occState)
+{
+  this->occupationState = occState;
+  this->notify_change_listeners_on_variable_change(constants::occupationState, (int) occState);
+
+  for (auto listener : this->componentChangeListeners)
+  {
+    listener.second->onNewOccupationState(occState);
+  }
+}
+
+std::string ControlComponent::getOccupierID()
+{
+  return this->occupier;
+}
+
+void ControlComponent::setOccupierID(const std::string &occId)
+{
+  this->occupier = occId;
+  this->notify_change_listeners_on_variable_change(constants::occupier, occId);
+
+  for (auto listener : this->componentChangeListeners)
+  {
+    listener.second->onNewOccupier(occId);
+  }
+}
+
+std::string ControlComponent::getLastOccupierID()
+{
+  return this->lastOccupier;
+}
+
+void ControlComponent::setLastOccupierID(const std::string &occId)
+{
+  this->lastOccupier = occId;
+  this->notify_change_listeners_on_variable_change(constants::lastOccupier, occId);
+
+  for (auto listener : this->componentChangeListeners)
+  {
+    listener.second->onLastOccupier(occId);
+  }
+}
+
+ExecutionMode ControlComponent::getExecutionMode()
+{
+  return this->exMode;
+}
+
+void ControlComponent::setExecutionMode(const ExecutionMode &exMode)
+{
+  this->exMode = exMode;
+  this->notify_change_listeners_on_variable_change(constants::exMode, (int) exMode);
+
+  for (auto listener : this->componentChangeListeners)
+  {
+    listener.second->onChangedExecutionMode(exMode);
+  }
+}
+
+ExecutionState ControlComponent::getExecutionState()
+{
+  return this->exState;
+}
+
+void ControlComponent::setExecutionState(const ExecutionState &newSt)
+{
+  this->exState = newSt;
+  this->notify_change_listeners_on_variable_change(constants::exState, ExecutionState_::to_string(newSt));
+
+  for (auto listener : this->componentChangeListeners)
+  {
+    listener.second->onChangedExecutionState(newSt);
+  }
+}
+
+std::string ControlComponent::getOperationMode()
+{
+  return this->opMode;
+}
+
+void ControlComponent::setOperationMode(const std::string &opMode)
+{
+  this->opMode = opMode;
+  this->notify_change_listeners_on_variable_change(constants::opMode, opMode);
+
+  for (auto listener : this->componentChangeListeners)
+  {
+    listener.second->onChangedOperationMode(opMode);
+  }
+}
+
+std::string ControlComponent::getWorkState()
+{
+  return this->workState;
+}
+
+void ControlComponent::setWorkState(const std::string &workState)
+{
+  this->workState = workState;
+  this->notify_change_listeners_on_variable_change(constants::workState, workState);
+
+  for (auto listener : this->componentChangeListeners)
+  {
+    listener.second->onChangedWorkState(workState);
+  }
+}
+
+std::string ControlComponent::getErrorState()
+{
+  return this->errorState;
+}
+
+void ControlComponent::setErrorState(const std::string &errorState)
+{
+  this->errorState = errorState;
+  this->notify_change_listeners_on_variable_change(constants::errorState, errorState);
+
+  for (auto listener : this->componentChangeListeners)
+  {
+    listener.second->onChangedErrorState(errorState);
+  }
+}
+
+std::string ControlComponent::getLastErrorState()
+{
+  return this->prevError;
+}
+
+void ControlComponent::setLastErrorState(const std::string &lastErrorState)
+{
+  this->errorState = lastErrorState;
+  this->notify_change_listeners_on_variable_change(constants::errorState, lastErrorState);
+
+  for (auto listener : this->componentChangeListeners)
+  {
+    listener.second->onChangedPrevError(lastErrorState);
+  }
+}
+
+std::string ControlComponent::getCommand()
+{
+  return this->cmd;
+}
+
+void ControlComponent::setCommand(const std::string &cmd)
+{
+  this->cmd = cmd;
+}
+
+std::string ControlComponent::getLocalOverwrite()
+{
+  return this->localOverwrite;
+}
+
+void ControlComponent::setLocalOverwrite(const std::string &cmd)
+{
+  this->localOverwrite = cmd;
+}
+
+std::string ControlComponent::getLocalOverwriteFree()
+{
+  return this->localOverwriteFree;
+}
+
+void ControlComponent::setLocalOverwriteFree(const std::string &cmd)
+{
+  this->localOverwriteFree = cmd;
+}
+
+void ControlComponent::changeExecutionState(const ExecutionOrder &ex_order)
+{
+  // Check if execution order leads to valid state in current state
+  switch (this->getExecutionState())
+  {
+    case ExecutionState::idle:
+      // Process expected orders
+      if (ex_order == ExecutionOrder::start)
+      {
+        this->setExecutionState(ExecutionState::starting);
+        return;
+      }
+      if (ex_order == ExecutionOrder::stop)
+      {
+        this->setExecutionState(ExecutionState::stopping);
+        return;
+      }
+      if (ex_order == ExecutionOrder::abort)
+      {
+        this->setExecutionState(ExecutionState::aborting);
+        return;
+      }
+
+    case ExecutionState::starting:
+      if (ex_order == ExecutionOrder::stop)
+      {
+        this->setExecutionState(ExecutionState::stopping);
+        return;
+      }
+      if (ex_order == ExecutionOrder::abort)
+      {
+        this->setExecutionState(ExecutionState::aborting);
+        return;
+      }
+
+    case ExecutionState::execute:
+      // Process expected orders
+      if (ex_order == ExecutionOrder::complete)
+      {
+        this->setExecutionState(ExecutionState::completing);
+        return;
+      }
+      if (ex_order == ExecutionOrder::hold)
+      {
+        this->setExecutionState(ExecutionState::holding);
+        return;
+      }
+      if (ex_order == ExecutionOrder::suspend)
+      {
+        this->setExecutionState(ExecutionState::suspending);
+        return;
+      }
+      if (ex_order == ExecutionOrder::stop)
+      {
+        this->setExecutionState(ExecutionState::stopping);
+        return;
+      }
+      if (ex_order == ExecutionOrder::abort)
+      {
+        this->setExecutionState(ExecutionState::aborting);
+        return;
+      }
+
+    case ExecutionState::completing:
+      if (ex_order == ExecutionOrder::stop)
+      {
+        this->setExecutionState(ExecutionState::stopping);
+        return;
+      }
+      if (ex_order == ExecutionOrder::abort)
+      {
+        this->setExecutionState(ExecutionState::aborting);
+        return;
+      }
+
+    case ExecutionState::complete:
+      if (ex_order == ExecutionOrder::reset)
+      {
+        this->setExecutionState(ExecutionState::resetting);
+        return;
+      }
+      if (ex_order == ExecutionOrder::stop)
+      {
+        this->setExecutionState(ExecutionState::stopping);
+        return;
+      }
+      if (ex_order == ExecutionOrder::abort)
+      {
+        this->setExecutionState(ExecutionState::aborting);
+        return;
+      }
+
+    case ExecutionState::resetting:
+      if (ex_order == ExecutionOrder::stop)
+      {
+        this->setExecutionState(ExecutionState::stopping);
+        return;
+      }
+      if (ex_order == ExecutionOrder::abort)
+      {
+        this->setExecutionState(ExecutionState::aborting);
+        return;
+      }
+
+    case ExecutionState::holding:
+      if (ex_order == ExecutionOrder::stop)
+      {
+        this->setExecutionState(ExecutionState::stopping);
+        return;
+      }
+      if (ex_order == ExecutionOrder::abort)
+      {
+        this->setExecutionState(ExecutionState::aborting);
+        return;
+      }
+
+    case ExecutionState::held:
+      if (ex_order == ExecutionOrder::unhold)
+      {
+        this->setExecutionState(ExecutionState::unholding);
+        return;
+      }
+      if (ex_order == ExecutionOrder::stop)
+      {
+        this->setExecutionState(ExecutionState::stopping);
+        return;
+      }
+      if (ex_order == ExecutionOrder::abort)
+      {
+        this->setExecutionState(ExecutionState::aborting);
+        return;
+      }
+
+    case ExecutionState::unholding:
+      if (ex_order == ExecutionOrder::stop)
+      {
+        this->setExecutionState(ExecutionState::stopping);
+        return;
+      }
+      if (ex_order == ExecutionOrder::abort)
+      {
+        this->setExecutionState(ExecutionState::aborting);
+        return;
+      }
+
+    case ExecutionState::suspending:
+      if (ex_order == ExecutionOrder::stop)
+      {
+        this->setExecutionState(ExecutionState::stopping);
+        return;
+      }
+      if (ex_order == ExecutionOrder::abort)
+      {
+        this->setExecutionState(ExecutionState::aborting);
+        return;
+      }
+
+    case ExecutionState::suspended:
+      if (ex_order == ExecutionOrder::unsuspend)
+      {
+        this->setExecutionState(ExecutionState::unsuspending);
+        return;
+      }
+      if (ex_order == ExecutionOrder::stop)
+      {
+        this->setExecutionState(ExecutionState::stopping);
+        return;
+      }
+      if (ex_order == ExecutionOrder::abort)
+      {
+        this->setExecutionState(ExecutionState::aborting);
+        return;
+      }
+
+    case ExecutionState::unsuspending:
+      if (ex_order == ExecutionOrder::stop)
+      {
+        this->setExecutionState(ExecutionState::stopping);
+        return;
+      }
+      if (ex_order == ExecutionOrder::abort)
+      {
+        this->setExecutionState(ExecutionState::aborting);
+        return;
+      }
+
+    case ExecutionState::stopping:
+      if (ex_order == ExecutionOrder::abort)
+      {
+        this->setExecutionState(ExecutionState::aborting);
+        return;
+      }
+
+    case ExecutionState::stopped:
+      if (ex_order == ExecutionOrder::reset)
+      {
+        this->setExecutionState(ExecutionState::resetting);
+        return;
+      }
+      if (ex_order == ExecutionOrder::abort)
+      {
+        this->setExecutionState(ExecutionState::aborting);
+        return;
+      }
+    case ExecutionState::aborted:
+      if (ex_order == ExecutionOrder::clear)
+      {
+        this->setExecutionState(ExecutionState::clearing);
+        return;
+      }
+
+    case ExecutionState::clearing:
+      if (ex_order == ExecutionOrder::abort)
+      {
+        this->setExecutionState(ExecutionState::aborting);
+        return;
+      }
+  }
+
+}
+
+void ControlComponent::invokeLocalOverwrite()
+{
+  // Store current occupier because we need to restore it later
+  this->savedOccupierId = this->getOccupierID();
+
+  // Enter local overwrite state
+  this->setOccupationState(OccupationState::local);
+  this->setOccupierID(constants_::to_string(constants::LOCAL));
+}
+
+void ControlComponent::clearLocalOverwrite()
+{
+  this->setOccupierID(this->savedOccupierId);
+
+  // Restore occupier state based on variables
+  if (this->savedOccupierId.empty())
+    this->setOccupationState(OccupationState::free);
+  else if (this->getLastOccupierID().empty())
+    this->setOccupationState(OccupationState::occupied);
+  else
+    this->setOccupationState(OccupationState::priority);
+}
+
+template<typename T> void ControlComponent::notify_change_listeners_on_variable_change(const ControlComponentConstants &status_key, T status)
+{
+  for (auto listener : this->componentChangeListeners)
+  {
+    listener.second->onVariableChange(constants_::to_string(status_key), status);
+  }
+}
+
+void ControlComponent::init_service_operations()
+{
+  // All lambdas returning bool since this is supported by vab
+  this->service_operations.insertKey(constants_::to_string(constants::free), object::make_function([this](std::string senderId) {
+    this->freeControlComponent(senderId);
+    return true;
+  }));
+  this->service_operations.insertKey(constants_::to_string(constants::occupy), object::make_function([this](std::string occupier) {
+    this->occupyControlComponent(occupier);
+    return true;
+  }));
+  this->service_operations.insertKey(constants_::to_string(constants::priority), object::make_function([this](std::string occupier) {
+    this->priorityOccupation(occupier);
+    return true;
+  }));
+
+  this->service_operations.insertKey(constants_::to_string(constants::Auto), object::make_function([this]() {
+    this->setExecutionMode(ExecutionMode::Auto);
+    return true;
+  }));
+  this->service_operations.insertKey(constants_::to_string(constants::semiauto), object::make_function([this]() {
+    this->setExecutionMode(ExecutionMode::Semiauto);
+    return true;
+  }));
+  this->service_operations.insertKey(constants_::to_string(constants::manual), object::make_function([this]() {
+    this->setExecutionMode(ExecutionMode::Manual);
+    return true;
+  }));
+  this->service_operations.insertKey(constants_::to_string(constants::simulation), object::make_function([this]() {
+    this->setExecutionMode(ExecutionMode::Simulation);
+    return true;
+  }));
+
+  this->service_operations.insertKey(constants_::to_string(constants::start), object::make_function([this]() {
+    this->changeExecutionState(ExecutionOrder::start);
+    return true;
+  }));
+  this->service_operations.insertKey(constants_::to_string(constants::reset), object::make_function([this]() {
+    this->changeExecutionState(ExecutionOrder::reset);
+    return true;
+  }));
+  this->service_operations.insertKey(constants_::to_string(constants::hold), object::make_function([this]() {
+    this->changeExecutionState(ExecutionOrder::hold);
+    return true;
+  }));
+  this->service_operations.insertKey(constants_::to_string(constants::unhold), object::make_function([this]() {
+    this->changeExecutionState(ExecutionOrder::unhold);
+    return true;
+  }));
+  this->service_operations.insertKey(constants_::to_string(constants::suspend), object::make_function([this]() {
+    this->changeExecutionState(ExecutionOrder::suspend);
+    return true;
+  }));
+  this->service_operations.insertKey(constants_::to_string(constants::unsuspend), object::make_function([this]() {
+    this->changeExecutionState(ExecutionOrder::unsuspend);
+    return true;
+  }));
+  this->service_operations.insertKey(constants_::to_string(constants::abort), object::make_function([this]() {
+    this->changeExecutionState(ExecutionOrder::abort);
+    return true;
+  }));
+  this->service_operations.insertKey(constants_::to_string(constants::stop), object::make_function([this]() {
+    this->changeExecutionState(ExecutionOrder::stop);
+    return true;
+  }));
+  this->service_operations.insertKey(constants_::to_string(constants::clear), object::make_function([this]() {
+    this->changeExecutionState(ExecutionOrder::clear);
+    return true;
+  }));
+
+  this->service_operations.insertKey(constants_::to_string(constants::bstate), object::make_function([this]() {
+    this->setOperationMode(std::string {"BSTATE"});
+    return true;
+  }));
+}
+
+void ControlComponent::freeControlComponent(const std::string &senderId)
+{
+  if (this->getOccupierID().compare(senderId) == 0)
+  {
+    this->setOccupierID(this->getLastOccupierID());
+    this->setLastOccupierID("");
+    if (this->getOccupierID().empty())
+      this->setOccupationState(OccupationState::free);
+    else
+      this->setOccupationState(OccupationState::occupied);
+  }
+}
+
+void ControlComponent::occupyControlComponent(const std::string &occupier)
+{
+  if (this->getOccupationState() == OccupationState::free)
+  {
+    this->setOccupierID(occupier);
+    this->setOccupationState(OccupationState::occupied);
+  }
+}
+
+void ControlComponent::priorityOccupation(const std::string &occupier)
+{
+  if ((this->getOccupationState() == OccupationState::free) or (this->getOccupationState() == OccupationState::occupied))
+  {
+    this->setLastOccupierID(this->getOccupierID());
+    this->setOccupierID(occupier);
+    this->setOccupationState(OccupationState::priority);
+  }
+}
+
+}
+}
+}
diff --git a/sdks/c++/basys.sdk.cc/src/logging/CMakeLists.txt b/sdks/c++/basys.sdk.cc/src/logging/CMakeLists.txt
index 5ebe52e..7b1c395 100644
--- a/sdks/c++/basys.sdk.cc/src/logging/CMakeLists.txt
+++ b/sdks/c++/basys.sdk.cc/src/logging/CMakeLists.txt
@@ -15,8 +15,10 @@
 set_target_properties(${BASYX_LOG_LIB_SUFFIX} PROPERTIES SOVERSION ${BASYX_PACKAGE_VERSION_MAJOR})
 set_target_properties(${BASYX_LOG_LIB_SUFFIX} PROPERTIES PREFIX "${CMAKE_STATIC_LIBRARY_PREFIX}${PROJECT_SHORTNAME}")
 target_include_directories(${BASYX_LOG_LIB_SUFFIX}
-INTERFACE ${CMAKE_INSTALL_PREFIX}/include
-       ${CMAKE_INSTALL_PREFIX}/include/${PROJECT_SHORTNAME})
+	PUBLIC 
+	    $<BUILD_INTERFACE:${BASYX_INCLUDE_DIR}>  
+		$<INSTALL_INTERFACE:${CMAKE_INSTALL_PREFIX}/include>
+)
 
 target_sources(${BASYX_LOG_LIB_SUFFIX}
     PRIVATE
@@ -38,7 +40,15 @@
 add_library(basyx::log ALIAS ${BASYX_LOG_LIB_SUFFIX})
 add_library(${PROJECT_SHORTNAME}::${BASYX_LOG_LIB_SUFFIX} ALIAS ${BASYX_LOG_LIB_SUFFIX})
 
-diagnostics_print(${BASYX_LOG_LIB_SUFFIX})
+if(BASYX_IS_SUBMODULE)
+	set_target_properties(${BASYX_LOG_LIB_SUFFIX} PROPERTIES FOLDER BaSyx)
+endif()
+
+if(BASYX_VERBOSE_CMAKE_OUTPUT)
+	diagnostics_print(${BASYX_LOG_LIB_SUFFIX})
+endif()
+
+build_source_group(${BASYX_LOG_LIB_SUFFIX})
 
 ###############################################
 ###           Install section               ###
diff --git a/sdks/c++/basys.sdk.cc/src/server/CMakeLists.txt b/sdks/c++/basys.sdk.cc/src/server/CMakeLists.txt
index 8d40802..367a9b6 100644
--- a/sdks/c++/basys.sdk.cc/src/server/CMakeLists.txt
+++ b/sdks/c++/basys.sdk.cc/src/server/CMakeLists.txt
@@ -14,8 +14,10 @@
 set_target_properties(${BASYX_SERVER_LIB_SUFFIX} PROPERTIES SOVERSION ${BASYX_PACKAGE_VERSION_MAJOR})
 set_target_properties(${BASYX_SERVER_LIB_SUFFIX} PROPERTIES PREFIX "${CMAKE_STATIC_LIBRARY_PREFIX}${PROJECT_SHORTNAME}")
 target_include_directories(${BASYX_SERVER_LIB_SUFFIX}
-INTERFACE ${CMAKE_INSTALL_PREFIX}/include
-       ${CMAKE_INSTALL_PREFIX}/include/${PROJECT_SHORTNAME})
+	PUBLIC 
+	    $<BUILD_INTERFACE:${BASYX_INCLUDE_DIR}>  
+		$<INSTALL_INTERFACE:${CMAKE_INSTALL_PREFIX}/include>
+)
 
 if(${BASYX_DEBUG_PRINT_FRAMES})
     target_compile_definitions(${BASYX_SERVER_LIB_SUFFIX} PUBLIC PRINT_FRAME)
@@ -23,6 +25,7 @@
 
 target_sources(${BASYX_SERVER_LIB_SUFFIX}
     PRIVATE
+	${CMAKE_CURRENT_SOURCE_DIR}/server/TCPServer.cpp
     ${BASYX_SHARED_INCLUDE_DIR}/TCPServer.h
     ${BASYX_SHARED_INCLUDE_DIR}/BaSyxNativeProvider.h
 )
@@ -43,7 +46,15 @@
 add_library(basyx::server ALIAS ${BASYX_SERVER_LIB_SUFFIX})
 add_library(${PROJECT_SHORTNAME}::${BASYX_SERVER_LIB_SUFFIX} ALIAS ${BASYX_SERVER_LIB_SUFFIX})
 
-diagnostics_print(${BASYX_SERVER_LIB_SUFFIX})
+if(BASYX_IS_SUBMODULE)
+	set_target_properties(${BASYX_SERVER_LIB_SUFFIX} PROPERTIES FOLDER BaSyx)
+endif()
+
+if(BASYX_VERBOSE_CMAKE_OUTPUT)
+	diagnostics_print(${BASYX_SERVER_LIB_SUFFIX})
+endif()
+
+build_source_group(${BASYX_SERVER_LIB_SUFFIX})
 
 ###############################################
 ###           Install section               ###
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/submodelelement/property/Property.cpp b/sdks/c++/basys.sdk.cc/src/server/server/TCPServer.cpp
similarity index 100%
rename from sdks/c++/basys.sdk.cc/src/submodel/submodel/map/submodelelement/property/Property.cpp
rename to sdks/c++/basys.sdk.cc/src/server/server/TCPServer.cpp
diff --git a/sdks/c++/basys.sdk.cc/src/shared/CMakeLists.txt b/sdks/c++/basys.sdk.cc/src/shared/CMakeLists.txt
index 98e2bc5..b477cb7 100644
--- a/sdks/c++/basys.sdk.cc/src/shared/CMakeLists.txt
+++ b/sdks/c++/basys.sdk.cc/src/shared/CMakeLists.txt
@@ -16,8 +16,10 @@
 set_target_properties(${BASYX_SHARED_TARGET_NAME} PROPERTIES SOVERSION ${BASYX_PACKAGE_VERSION_MAJOR})
 set_target_properties(${BASYX_SHARED_TARGET_NAME} PROPERTIES PREFIX "${CMAKE_STATIC_LIBRARY_PREFIX}${PROJECT_SHORTNAME}")
 target_include_directories(${BASYX_SHARED_TARGET_NAME}
-INTERFACE ${CMAKE_INSTALL_PREFIX}/include
-       ${CMAKE_INSTALL_PREFIX}/include/${PROJECT_SHORTNAME})
+	PUBLIC 
+	    $<BUILD_INTERFACE:${BASYX_INCLUDE_DIR}>  
+		$<INSTALL_INTERFACE:${CMAKE_INSTALL_PREFIX}/include>
+)
 
 target_sources(${BASYX_SHARED_TARGET_NAME}
     PRIVATE
@@ -63,7 +65,15 @@
 add_library(basyx::shared ALIAS ${BASYX_SHARED_TARGET_NAME})
 add_library(${PROJECT_SHORTNAME}::${BASYX_SHARED_LIB_SUFFIX} ALIAS ${BASYX_SHARED_TARGET_NAME})
 
-diagnostics_print(${BASYX_SHARED_TARGET_NAME})
+if(BASYX_IS_SUBMODULE)
+	set_target_properties(${BASYX_SHARED_TARGET_NAME} PROPERTIES FOLDER BaSyx)
+endif()
+
+if(BASYX_VERBOSE_CMAKE_OUTPUT)
+	diagnostics_print(${BASYX_SHARED_TARGET_NAME})
+endif()
+
+build_source_group(${BASYX_SHARED_TARGET_NAME})
 
 ###############################################
 ###           Install section               ###
diff --git a/sdks/c++/basys.sdk.cc/src/shared/shared/object/impl/object_impl.cpp b/sdks/c++/basys.sdk.cc/src/shared/shared/object/impl/object_impl.cpp
index 257e74d..d251e0c 100644
--- a/sdks/c++/basys.sdk.cc/src/shared/shared/object/impl/object_impl.cpp
+++ b/sdks/c++/basys.sdk.cc/src/shared/shared/object/impl/object_impl.cpp
@@ -4,278 +4,273 @@
 #include <BaSyx/shared/object/obj_error_holder.h>
 
 basyx::object::object()
-	: content{ nullptr } {};
+    : content{ nullptr } {};
 
 basyx::object::object(const char * c)
-	: object{ std::string(c) }
+    : object{ std::string(c) }
 {
 };
 
 bool basyx::object::empty()
 {
-	if (!this->content)
-		return true;
+    if (!this->content)
+        return true;
 
-	auto object_type = this->GetObjectType();
-	auto value_type = this->GetValueType();
+    auto object_type = this->GetObjectType();
+    auto value_type = this->GetValueType();
 
-	if (object_type == basyx::type::objectType::Primitive)
-		return false;
+    if (object_type == basyx::type::objectType::Primitive)
+        return false;
 
-	switch (this->content->object_type())
-	{
-	case basyx::type::objectType::List:
-		switch (value_type)
-		{
-		case basyx::type::valueType::Bool:
-			return this->Get<object::list_t<bool>&>().empty();
-			break;
-		case basyx::type::valueType::Int:
-			return this->Get<object::list_t<int>&>().empty();
-			break;
-		case basyx::type::valueType::Float:
-			return this->Get<object::list_t<double>&>().empty();
-			break;
-		case basyx::type::valueType::String:
-			return this->Get<object::list_t<std::string>&>().empty();
-			break;
-		case basyx::type::valueType::Object:
-			return this->Get<object::object_list_t&>().empty();
-			break;
-		};
-	case basyx::type::objectType::Map:
-		return this->Get<object::object_map_t&>().empty();
-		break;
-	}
+    switch (this->content->object_type())
+    {
+    case basyx::type::objectType::List:
+        switch (value_type)
+        {
+        case basyx::type::valueType::Bool:
+            return this->Get<object::list_t<bool>&>().empty();
+        case basyx::type::valueType::Int:
+            return this->Get<object::list_t<int>&>().empty();
+        case basyx::type::valueType::Float:
+            return this->Get<object::list_t<double>&>().empty();
+        case basyx::type::valueType::String:
+            return this->Get<object::list_t<std::string>&>().empty();
+        case basyx::type::valueType::Object:
+            return this->Get<object::object_list_t&>().empty();
+        default:
+            break;
+        };
+    case basyx::type::objectType::Map:
+        return this->Get<object::object_map_t&>().empty();
+    default:
+        break;
+    }
 
-	return true;
+    return true;
 };
 
 bool basyx::object::insert(basyx::object obj)
 {
-	if (!this->content)
-		return false;
+    if (!this->content)
+        return false;
 
-	auto object_type = obj.content->object_type();
-	auto value_type = obj.content->value_type();
+    auto object_type = obj.content->object_type();
+    auto value_type = obj.content->value_type();
 
-	//if (object_type != basyx::type::objectType::Primitive)
-	//	return false;
+    //if (object_type != basyx::type::objectType::Primitive)
+    //    return false;
 
-	switch (this->content->object_type())
-	{
-	case basyx::type::objectType::List:
-		if (this->content->value_type() == basyx::type::valueType::Object)
-		{
-			this->Get<basyx::object::object_list_t&>().emplace_back(obj);
-			return true;
-		}
+    switch (this->content->object_type())
+    {
+    case basyx::type::objectType::List:
+        if (this->content->value_type() == basyx::type::valueType::Object)
+        {
+            this->Get<basyx::object::object_list_t&>().emplace_back(obj);
+            return true;
+        }
 
-		if (this->content->value_type() == value_type)
-		{
-			switch (value_type)
-			{
-			case basyx::type::valueType::Bool:
-				return this->insert(obj.Get<bool&>());
-				break;
-			case basyx::type::valueType::Int:
-				return this->insert(obj.Get<int&>());
-				break;
-			case basyx::type::valueType::Float:
-				return this->insert(obj.Get<float&>());
-				break;
-			case basyx::type::valueType::String:
-				return this->insert(obj.Get<std::string&>());
-				break;
-			};
-		}
-		break;
-	};
+        if (this->content->value_type() == value_type)
+        {
+            switch (value_type)
+            {
+            case basyx::type::valueType::Bool:
+                return this->insert(obj.Get<bool&>());
+            case basyx::type::valueType::Int:
+                return this->insert(obj.Get<int&>());
+            case basyx::type::valueType::Float:
+                return this->insert(obj.Get<float&>());
+            case basyx::type::valueType::String:
+                return this->insert(obj.Get<std::string&>());
+            default:
+                break;
+            };
+        };
+    default:
+        break;
+    };
 
-	return false;
+    return false;
 };
 
 bool basyx::object::hasProperty(const std::string & propertyName)
 {
-	if (!this->content || this->GetObjectType() != basyx::type::objectType::Map)
-		return false;
+    if (!this->content || this->GetObjectType() != basyx::type::objectType::Map)
+        return false;
 
-	auto & map = this->Get<basyx::object::object_map_t&>();
+    auto & map = this->Get<basyx::object::object_map_t&>();
 
-	if (map.find(propertyName) != map.end()) {
-		return true;
-	}
+    if (map.find(propertyName) != map.end()) {
+        return true;
+    }
 
-	return false;
+    return false;
 };
 
 basyx::object basyx::object::getProperty(const std::string & propertyName)
 {
-	if (!this->content || this->GetObjectType() != basyx::type::objectType::Map)
-		return basyx::object::make_error(error::PropertyNotFound, "Property access only supported on maps!");
+    if (!this->content || this->GetObjectType() != basyx::type::objectType::Map)
+        return basyx::object::make_error(error::PropertyNotFound, "Property access only supported on maps!");
 
-	auto & map = this->Get<basyx::object::object_map_t&>();
+    auto & map = this->Get<basyx::object::object_map_t&>();
 
-	if (map.find(propertyName) != map.end()) {
-		return map[propertyName];
-	}
+    if (map.find(propertyName) != map.end()) {
+        return map[propertyName];
+    }
 
-	return basyx::object::make_error(error::PropertyNotFound, "Property " + propertyName + " not found!");
+    return basyx::object::make_error(error::PropertyNotFound, "Property " + propertyName + " not found!");
 };
 
 bool basyx::object::removeProperty(const std::string & propertyName)
 {
-	if (!this->content)
-		return false;
+    if (!this->content)
+        return false;
 
-	if (this->InstanceOf<object::object_map_t>())
-	{
-		auto & map = this->Get<object::object_map_t&>();
-		auto found = map.find(propertyName);
-		if (found != map.end()) {
-			map.erase(found);
-			return true;
-		}
-	};
+    if (this->InstanceOf<object::object_map_t>())
+    {
+        auto & map = this->Get<object::object_map_t&>();
+        auto found = map.find(propertyName);
+        if (found != map.end()) {
+            map.erase(found);
+            return true;
+        }
+    };
 
-	return false;
+    return false;
 };
 
 bool basyx::object::operator==(const basyx::object& rhs) const
 {
-	if (rhs.IsNull())
-		return false;
+    if (rhs.IsNull())
+        return false;
 
-	return this->content->compare(rhs.content.get());
+    return this->content->compare(rhs.content.get());
 }
 
 std::size_t basyx::object::size()
 {
-	if (!this->content)
-		return -1;
+    if (!this->content)
+        return -1;
 
-	auto valueType = this->GetValueType();
+    auto valueType = this->GetValueType();
 
-	// Check if contained object is list or set
-	switch (content->object_type())
-	{
-	case basyx::type::objectType::List:
-		switch (valueType)
-		{
-		case basyx::type::valueType::Bool:
-			return this->Get<object::list_t<bool>&>().size();
-			break;
-		case basyx::type::valueType::Int:
-			return this->Get<object::list_t<int>&>().size();
-			break;
-		case basyx::type::valueType::Float:
-			return this->Get<object::list_t<float>&>().size();
-			break;
-		case basyx::type::valueType::String:
-			return this->Get<object::list_t<std::string>&>().size();
-			break;
-		case basyx::type::valueType::Object:
-			return this->Get<object::object_list_t&>().size();
-			break;
-		};
-		break;
-	case basyx::type::objectType::Map:
-		return this->Get<object::object_map_t&>().size();
-		break;
-	};
+    // Check if contained object is list or set
+    switch (content->object_type())
+    {
+    case basyx::type::objectType::List:
+        switch (valueType)
+        {
+        case basyx::type::valueType::Bool:
+            return this->Get<object::list_t<bool>&>().size();
+        case basyx::type::valueType::Int:
+            return this->Get<object::list_t<int>&>().size();
+        case basyx::type::valueType::Float:
+            return this->Get<object::list_t<float>&>().size();
+        case basyx::type::valueType::String:
+            return this->Get<object::list_t<std::string>&>().size();
+        case basyx::type::valueType::Object:
+            return this->Get<object::object_list_t&>().size();
+        default:
+            break;
+        };
+        break;
+    case basyx::type::objectType::Map:
+        return this->Get<object::object_map_t&>().size();
+    default:
+        break;
+    };
 
-	return 1;
+    return 1;
 };
 
 basyx::object basyx::object::make_null()
 {
-	return basyx::object{ nullptr };
+    return basyx::object{ nullptr };
 };
 
 basyx::object basyx::object::make_error(basyx::object::error error_code)
 {
-	basyx::object obj;
-	obj.content = std::make_shared<basyx::detail::objErrorHolder>(error_code);
-	return obj;
+    basyx::object obj;
+    obj.content = std::make_shared<basyx::detail::objErrorHolder>(error_code);
+    return obj;
 };
 
 basyx::object basyx::object::make_error(basyx::object::error error_code, const std::string & msg)
 {
-	basyx::object obj;
-	obj.content = std::make_shared<basyx::detail::objErrorHolder>(error_code, msg);
-	return obj;
+    basyx::object obj;
+    obj.content = std::make_shared<basyx::detail::objErrorHolder>(error_code, msg);
+    return obj;
 };
 
 basyx::object::error basyx::object::getError() const
 {
-	if (this->GetObjectType() != basyx::type::objectType::Error)
-		return basyx::object::error::None;
+    if (this->GetObjectType() != basyx::type::objectType::Error)
+        return basyx::object::error::None;
 
-	auto & errorHolder = dynamic_cast<basyx::detail::objErrorHolder&>(*this->content);
-	return errorHolder.error;
+    auto & errorHolder = dynamic_cast<basyx::detail::objErrorHolder&>(*this->content);
+    return errorHolder.error;
 }
 
 const std::string & basyx::object::getErrorMessage() const
 {
-	auto & errorHolder = dynamic_cast<basyx::detail::objErrorHolder&>(*this->content);
-	return errorHolder.message;
+    auto & errorHolder = dynamic_cast<basyx::detail::objErrorHolder&>(*this->content);
+    return errorHolder.message;
 }
 
 basyx::object basyx::object::invoke()
 {
-	if (this->IsNull() || this->GetObjectType() != basyx::type::objectType::Function)
-		return basyx::object::make_error(basyx::object::error::NotInvokable, "Object not invokable!");
+    if (this->IsNull() || this->GetObjectType() != basyx::type::objectType::Function)
+        return basyx::object::make_error(basyx::object::error::NotInvokable, "Object not invokable!");
 
-	return this->Get<basyx::detail::functionWrapper>().invoke();
+    return this->Get<basyx::detail::functionWrapper>().invoke();
 };
 
 basyx::object basyx::object::invoke(basyx::object& obj)
 {
-	if (this->IsNull() || this->GetObjectType() != basyx::type::objectType::Function)
-		return basyx::object::make_error(basyx::object::error::NotInvokable, "Object not invokable!");
+    if (this->IsNull() || this->GetObjectType() != basyx::type::objectType::Function)
+        return basyx::object::make_error(basyx::object::error::NotInvokable, "Object not invokable!");
 
-	auto param = obj;
+    auto param = obj;
 
-	auto object_type = obj.GetObjectType();
-	auto value_type = obj.GetValueType();
+    auto object_type = obj.GetObjectType();
+    auto value_type = obj.GetValueType();
 
-	// Transpose to object list if necessary
-	if (object_type == basyx::type::objectType::List)
-	{
-		if (value_type == basyx::type::valueType::Bool)
-		{
-			auto & list = obj.Get<basyx::object::list_t<bool>&>();
-			param = basyx::object::make_list<basyx::object>();
-			for (bool b : list) {
-				param.insert(basyx::object{ b });
-			};
-		}
-		else if (value_type == basyx::type::valueType::Int)
-		{
-			auto & list = obj.Get<basyx::object::list_t<int>&>();
-			param = basyx::object::make_list<basyx::object>(list.begin(), list.end());
-		}
-		else if (value_type == basyx::type::valueType::Float)
-		{
-			auto & list = obj.Get<basyx::object::list_t<double>&>();
-			param = basyx::object::make_list<basyx::object>(list.begin(), list.end());
-		}
-		else if (value_type == basyx::type::valueType::String)
-		{
-			auto & list = obj.Get<basyx::object::list_t<std::string>&>();
-			param = basyx::object::make_list<basyx::object>();
-			for (auto & str : list)	{
-				param.insert(basyx::object::make_object_ref(&str));
-			};
-		}
-	};
+    // Transpose to object list if necessary
+    if (object_type == basyx::type::objectType::List)
+    {
+        if (value_type == basyx::type::valueType::Bool)
+        {
+            auto & list = obj.Get<basyx::object::list_t<bool>&>();
+            param = basyx::object::make_list<basyx::object>();
+            for (bool b : list) {
+                param.insert(basyx::object{ b });
+            };
+        }
+        else if (value_type == basyx::type::valueType::Int)
+        {
+            auto & list = obj.Get<basyx::object::list_t<int>&>();
+            param = basyx::object::make_list<basyx::object>(list.begin(), list.end());
+        }
+        else if (value_type == basyx::type::valueType::Float)
+        {
+            auto & list = obj.Get<basyx::object::list_t<double>&>();
+            param = basyx::object::make_list<basyx::object>(list.begin(), list.end());
+        }
+        else if (value_type == basyx::type::valueType::String)
+        {
+            auto & list = obj.Get<basyx::object::list_t<std::string>&>();
+            param = basyx::object::make_list<basyx::object>();
+            for (auto & str : list)    {
+                param.insert(basyx::object::make_object_ref(&str));
+            };
+        }
+    };
 
-	return this->Get<basyx::detail::functionWrapper>().invoke(param);
+    return this->Get<basyx::detail::functionWrapper>().invoke(param);
 };
 
 void basyx::to_json(nlohmann::json& json, const basyx::object& object)
 {
-	object.content->to_json(json);
+    object.content->to_json(json);
 };
 
 
@@ -290,4 +285,4 @@
 constexpr basyx::type::valueType basyx::type::basyx_type<std::string>::value_type;
 
 constexpr basyx::type::objectType basyx::type::basyx_type<basyx::detail::functionWrapper>::object_type;
-constexpr basyx::type::valueType basyx::type::basyx_type<basyx::detail::functionWrapper>::value_type;
\ No newline at end of file
+constexpr basyx::type::valueType basyx::type::basyx_type<basyx::detail::functionWrapper>::value_type;
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/CMakeLists.txt b/sdks/c++/basys.sdk.cc/src/submodel/CMakeLists.txt
index cfd61d2..3d25e32 100644
--- a/sdks/c++/basys.sdk.cc/src/submodel/CMakeLists.txt
+++ b/sdks/c++/basys.sdk.cc/src/submodel/CMakeLists.txt
@@ -17,12 +17,15 @@
 set_target_properties(${BASYX_SUBMODEL_LIB_SUFFIX} PROPERTIES SOVERSION ${BASYX_PACKAGE_VERSION_MAJOR})
 set_target_properties(${BASYX_SUBMODEL_LIB_SUFFIX} PROPERTIES PREFIX "${CMAKE_STATIC_LIBRARY_PREFIX}${PROJECT_SHORTNAME}")
 target_include_directories(${BASYX_SUBMODEL_LIB_SUFFIX}
-INTERFACE ${CMAKE_INSTALL_PREFIX}/include
-       ${CMAKE_INSTALL_PREFIX}/include/${PROJECT_SHORTNAME})
-
+	PUBLIC 
+	    $<BUILD_INTERFACE:${BASYX_INCLUDE_DIR}>  
+		$<INSTALL_INTERFACE:${CMAKE_INSTALL_PREFIX}/include>
+)
 
 target_sources(${BASYX_SUBMODEL_LIB_SUFFIX}
     PRIVATE
+		${CMAKE_CURRENT_SOURCE_DIR}/submodel/map_v2/constexpr.cpp
+
 	    ${CMAKE_CURRENT_SOURCE_DIR}/submodel/enumerations/AssetKind.cpp
         ${CMAKE_CURRENT_SOURCE_DIR}/submodel/enumerations/DataTypeIEC61360.cpp
         ${CMAKE_CURRENT_SOURCE_DIR}/submodel/enumerations/LevelType.cpp
@@ -45,6 +48,7 @@
 		${CMAKE_CURRENT_SOURCE_DIR}/submodel/map_v2/parts/ConceptDictionary.cpp
 		${CMAKE_CURRENT_SOURCE_DIR}/submodel/map_v2/parts/ConceptDescription.cpp
 		${CMAKE_CURRENT_SOURCE_DIR}/submodel/map_v2/parts/View.cpp
+		${CMAKE_CURRENT_SOURCE_DIR}/submodel/map_v2/qualifier/AdministrativeInformation.cpp
         ${CMAKE_CURRENT_SOURCE_DIR}/submodel/map_v2/qualifier/HasDataSpecification.cpp
         ${CMAKE_CURRENT_SOURCE_DIR}/submodel/map_v2/qualifier/Identifiable.cpp
 		${CMAKE_CURRENT_SOURCE_DIR}/submodel/map_v2/qualifier/Qualifiable.cpp
@@ -66,6 +70,18 @@
         ${CMAKE_CURRENT_SOURCE_DIR}/submodel/simple/aas/AssetAdministrationShell.cpp
         ${CMAKE_CURRENT_SOURCE_DIR}/submodel/simple/aas/Asset.cpp
         ${CMAKE_CURRENT_SOURCE_DIR}/submodel/simple/common/LangStringSet.cpp
+		${CMAKE_CURRENT_SOURCE_DIR}/submodel/simple/common/xsd_types/Timezone.cpp
+		${CMAKE_CURRENT_SOURCE_DIR}/submodel/simple/common/xsd_types/AnyURI.cpp
+		${CMAKE_CURRENT_SOURCE_DIR}/submodel/simple/common/xsd_types/DateTime.cpp
+		${CMAKE_CURRENT_SOURCE_DIR}/submodel/simple/common/xsd_types/Date.cpp
+		${CMAKE_CURRENT_SOURCE_DIR}/submodel/simple/common/xsd_types/DayTimeDuration.cpp
+		${CMAKE_CURRENT_SOURCE_DIR}/submodel/simple/common/xsd_types/YearMonthDuration.cpp
+		${CMAKE_CURRENT_SOURCE_DIR}/submodel/simple/common/xsd_types/Time.cpp
+		${CMAKE_CURRENT_SOURCE_DIR}/submodel/simple/common/xsd_types/GYearMonth.cpp
+		${CMAKE_CURRENT_SOURCE_DIR}/submodel/simple/common/xsd_types/GYear.cpp
+		${CMAKE_CURRENT_SOURCE_DIR}/submodel/simple/common/xsd_types/GMonthDay.cpp
+		${CMAKE_CURRENT_SOURCE_DIR}/submodel/simple/common/xsd_types/GDay.cpp
+		${CMAKE_CURRENT_SOURCE_DIR}/submodel/simple/common/xsd_types/GMonth.cpp
         ${CMAKE_CURRENT_SOURCE_DIR}/submodel/simple/constraint/Formula.cpp
         ${CMAKE_CURRENT_SOURCE_DIR}/submodel/simple/constraint/Qualifier.cpp
         ${CMAKE_CURRENT_SOURCE_DIR}/submodel/simple/dataspecification/DataSpecification.cpp
@@ -110,6 +126,7 @@
 		${BASYX_SUBMODEL_INCLUDE_DIR}/enumerations/KeyType.h
 		${BASYX_SUBMODEL_INCLUDE_DIR}/enumerations/KeyElements.h
 		${BASYX_SUBMODEL_INCLUDE_DIR}/enumerations/IdentifiableElements.h
+		${BASYX_SUBMODEL_INCLUDE_DIR}/enumerations/Conversions.h
 	
         ${BASYX_SUBMODEL_INCLUDE_DIR}/api_v2/aas/IAssetAdministrationShell.h
         ${BASYX_SUBMODEL_INCLUDE_DIR}/api_v2/aas/IAsset.h
@@ -130,6 +147,7 @@
         ${BASYX_SUBMODEL_INCLUDE_DIR}/api_v2/parts/IConceptDescription.h
 		${BASYX_SUBMODEL_INCLUDE_DIR}/api_v2/parts/IConceptDictionary.h
 		${BASYX_SUBMODEL_INCLUDE_DIR}/api_v2/parts/IView.h
+		${BASYX_SUBMODEL_INCLUDE_DIR}/api_v2/qualifier/IAdministrativeInformation.h
         ${BASYX_SUBMODEL_INCLUDE_DIR}/api_v2/qualifier/IHasDataSpecification.h
         ${BASYX_SUBMODEL_INCLUDE_DIR}/api_v2/qualifier/IHasKind.h
         ${BASYX_SUBMODEL_INCLUDE_DIR}/api_v2/qualifier/IHasSemantics.h
@@ -148,6 +166,7 @@
         ${BASYX_SUBMODEL_INCLUDE_DIR}/api_v2/submodelelement/operation/IOperationVariable.h
         ${BASYX_SUBMODEL_INCLUDE_DIR}/api_v2/submodelelement/property/IMultiLanguageProperty.h
         ${BASYX_SUBMODEL_INCLUDE_DIR}/api_v2/submodelelement/property/IProperty.h
+		${BASYX_SUBMODEL_INCLUDE_DIR}/api_v2/submodelelement/property/XSDAnySimpleType.h
         ${BASYX_SUBMODEL_INCLUDE_DIR}/api_v2/submodelelement/property/IReferenceElement.h
 		${BASYX_SUBMODEL_INCLUDE_DIR}/api_v2/submodelelement/IRelationshipElement.h
 		${BASYX_SUBMODEL_INCLUDE_DIR}/api_v2/submodelelement/IAnnotatedRelationshipElement.h
@@ -159,6 +178,7 @@
         ${BASYX_SUBMODEL_INCLUDE_DIR}/map_v2/aas/AssetAdministrationShell.h
         ${BASYX_SUBMODEL_INCLUDE_DIR}/map_v2/aas/Asset.h
         ${BASYX_SUBMODEL_INCLUDE_DIR}/map_v2/common/ElementContainer.h
+        ${BASYX_SUBMODEL_INCLUDE_DIR}/map_v2/common/SubModelContainer.h
         ${BASYX_SUBMODEL_INCLUDE_DIR}/map_v2/common/ElementFactory.h
         ${BASYX_SUBMODEL_INCLUDE_DIR}/map_v2/common/LangStringSet.h
         ${BASYX_SUBMODEL_INCLUDE_DIR}/map_v2/common/ModelType.h
@@ -171,6 +191,7 @@
 		${BASYX_SUBMODEL_INCLUDE_DIR}/map_v2/parts/View.h
 		${BASYX_SUBMODEL_INCLUDE_DIR}/map_v2/constraint/Formula.h
 		${BASYX_SUBMODEL_INCLUDE_DIR}/map_v2/constraint/Qualifier.h
+		${BASYX_SUBMODEL_INCLUDE_DIR}/map_v2/qualifier/AdministrativeInformation.h
         ${BASYX_SUBMODEL_INCLUDE_DIR}/map_v2/qualifier/HasDataSpecification.h
         ${BASYX_SUBMODEL_INCLUDE_DIR}/map_v2/qualifier/Identifiable.h
         ${BASYX_SUBMODEL_INCLUDE_DIR}/map_v2/qualifier/Qualifiable.h
@@ -192,6 +213,18 @@
         ${BASYX_SUBMODEL_INCLUDE_DIR}/simple/aas/Asset.h
         ${BASYX_SUBMODEL_INCLUDE_DIR}/simple/common/ElementContainer.h
         ${BASYX_SUBMODEL_INCLUDE_DIR}/simple/common/LangStringSet.h
+		${BASYX_SUBMODEL_INCLUDE_DIR}/simple/common/xsd_types/Timezone.h
+		${BASYX_SUBMODEL_INCLUDE_DIR}/simple/common/xsd_types/AnyURI.h
+		${BASYX_SUBMODEL_INCLUDE_DIR}/simple/common/xsd_types/DateTime.h
+		${BASYX_SUBMODEL_INCLUDE_DIR}/simple/common/xsd_types/Date.h
+		${BASYX_SUBMODEL_INCLUDE_DIR}/simple/common/xsd_types/DayTimeDuration.h
+		${BASYX_SUBMODEL_INCLUDE_DIR}/simple/common/xsd_types/YearMonthDuration.h
+		${BASYX_SUBMODEL_INCLUDE_DIR}/simple/common/xsd_types/Time.h
+		${BASYX_SUBMODEL_INCLUDE_DIR}/simple/common/xsd_types/GYearMonth.h
+		${BASYX_SUBMODEL_INCLUDE_DIR}/simple/common/xsd_types/GYear.h
+		${BASYX_SUBMODEL_INCLUDE_DIR}/simple/common/xsd_types/GMonthDay.h
+		${BASYX_SUBMODEL_INCLUDE_DIR}/simple/common/xsd_types/GDay.h
+		${BASYX_SUBMODEL_INCLUDE_DIR}/simple/common/xsd_types/GMonth.h
 		${BASYX_SUBMODEL_INCLUDE_DIR}/simple/constraint/Formula.h
 		${BASYX_SUBMODEL_INCLUDE_DIR}/simple/constraint/Qualifier.h
         ${BASYX_SUBMODEL_INCLUDE_DIR}/simple/dataspecification/DataSpecification.h
@@ -233,7 +266,20 @@
 add_library(basyx::submodel ALIAS ${BASYX_SUBMODEL_LIB_SUFFIX})
 add_library(${PROJECT_SHORTNAME}::${BASYX_SUBMODEL_LIB_SUFFIX} ALIAS ${BASYX_SUBMODEL_LIB_SUFFIX})
 
-diagnostics_print(${BASYX_SUBMODEL_LIB_SUFFIX})
+# Disable inheritance by dominance warning in MSVC
+if(MSVC)
+	target_compile_options(${BASYX_SUBMODEL_LIB_SUFFIX} PUBLIC /wd4250)
+endif()
+
+if(BASYX_IS_SUBMODULE)
+	set_target_properties(${BASYX_SUBMODEL_LIB_SUFFIX} PROPERTIES FOLDER BaSyx)
+endif()
+
+if(BASYX_VERBOSE_CMAKE_OUTPUT)
+	diagnostics_print(${BASYX_SUBMODEL_LIB_SUFFIX})
+endif()
+
+build_source_group(${BASYX_SUBMODEL_LIB_SUFFIX})
 
 ###############################################
 ###           Install section               ###
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/api/constant_definitions.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/api/constant_definitions.cpp
deleted file mode 100644
index 7e1a3d6..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/api/constant_definitions.cpp
+++ /dev/null
@@ -1,160 +0,0 @@
-#include <BaSyx/submodel/map/modeltype/ModelType.h>
-#include <BaSyx/submodel/map/identifier/IdentifierType.h>
-#include <BaSyx/submodel/api/identifier/IIdentifier.h>
-#include <BaSyx/submodel/api/qualifier/IReferable.h>
-#include <BaSyx/submodel/api/qualifier/IHasSemantics.h>
-#include <BaSyx/submodel/api/qualifier/IHasKind.h>
-#include <BaSyx/submodel/api/qualifier/IHasDataSpecification.h>
-#include <BaSyx/submodel/api/qualifier/IAdministrativeInformation.h>
-#include <BaSyx/submodel/api/qualifier/qualifiable/IQualifier.h>
-#include <BaSyx/submodel/api/qualifier/qualifiable/IQualifiable.h>
-#include <BaSyx/submodel/api/qualifier/qualifiable/IConstraint.h>
-#include <BaSyx/submodel/api/submodelelement/ISubmodelElement.h>
-#include <BaSyx/submodel/api/submodelelement/operation/IOperation.h>
-#include <BaSyx/submodel/api/submodelelement/operation/IOperationVariable.h>
-#include <BaSyx/submodel/api/submodelelement/property/IProperty.h>
-#include <BaSyx/submodel/api/reference/IReference.h>
-#include <BaSyx/submodel/api/ISubModel.h>
-#include <BaSyx/submodel/api/qualifier/qualifiable/IFormula.h>
-#include <BaSyx/submodel/api/qualifier/IIdentifiable.h>
-#include <BaSyx/submodel/api/submodelelement/IReferenceElement.h>
-#include <BaSyx/submodel/api/submodelelement/IRelationshipElement.h>
-#include <BaSyx/submodel/api/submodelelement/ISubmodelElementCollection.h>
-
-#include <BaSyx/submodel/api/submodelelement/property/blob/IBlob.h>
-#include <BaSyx/submodel/api/submodelelement/property/file/IFile.h>
-
-#include <BaSyx/submodel/api/submodelelement/langstring/ILangStringSet.h>
-
-#include <BaSyx/submodel/api/dataspecification/datatypes/DataTypeIEC61360.h>
-#include <BaSyx/submodel/api/dataspecification/datatypes/LevelType.h>
-#include <BaSyx/submodel/api/dataspecification/IDataSpecificationContent.h>
-#include <BaSyx/submodel/api/dataspecification/IDataSpecification.h>
-#include <BaSyx/submodel/api/dataspecification/IDataSpecificationIEC61360.h>
-
-
-#include <BaSyx/submodel/api/submodelelement/entity/IEntity.h>
-#include <BaSyx/submodel/api/parts/IConceptDescription.h>
-
-
-namespace basyx {
-namespace submodel {
-
-constexpr char IOperationVariable::Path::Type[];
-constexpr char IOperationVariable::Path::ModelType[];
-constexpr char IOperationVariable::Path::Value[];
-
-constexpr char IProperty::Path::Value[];
-constexpr char IProperty::Path::ValueId[];
-constexpr char IProperty::Path::ValueType[];
-constexpr char IProperty::Path::ModelType[];
-
-constexpr char IOperation::Path::Input[];
-constexpr char IOperation::Path::Output[];
-constexpr char IOperation::Path::Invokable[];
-constexpr char IOperation::Path::ModelType[];
-
-constexpr char IReference::Path::DataSpecifications[];
-constexpr char IReference::Path::Key[];
-constexpr char IReference::Path::Parents[];
-constexpr char IReference::Path::Qualifiers[];
-constexpr char IReference::Path::ReferencePath[];
-constexpr char IReference::Path::SemanticIds[];
-
-constexpr char IConstraint::Path::ModelType[];
-
-constexpr char ISubmodelElement::Path::ModelType[];
-
-constexpr char ModelType::Path::ModelType[];
-constexpr char ModelType::Path::Name[];
-
-constexpr char IReferable::Path::IdShort[];
-constexpr char IReferable::Path::Category[];
-constexpr char IReferable::Path::Description[];
-constexpr char IReferable::Path::Parent[];
-
-constexpr char IHasSemantics::Path::SemanticId[];
-
-constexpr char IHasKind::Path::Kind[];
-
-constexpr char IQualifier::Path::Qualifier[];
-constexpr char IQualifier::Path::QualifierType[];
-constexpr char IQualifier::Path::QualifierValue[];
-constexpr char IQualifier::Path::QualifierValueID[];
-constexpr char IQualifier::Path::Modeltype[];
-
-constexpr char IQualifiable::Path::Constraints[];
-
-constexpr char IHasDataSpecification::Path::HasDataSpecification[];
-
-constexpr char IIdentifier::Path::IdentifierPath[];
-constexpr char IIdentifier::Path::IdType[];
-constexpr char IIdentifier::Path::Id[];
-
-constexpr char IAdministrativeInformation::Path::AdministrationPath[];
-constexpr char IAdministrativeInformation::Path::Version[];
-constexpr char IAdministrativeInformation::Path::Revision[];
-
-constexpr char ISubModel::Path::Submodelelement[];
-constexpr char ISubModel::Path::DataElements[];
-constexpr char ISubModel::Path::Operations[];
-constexpr char ISubModel::Path::ModelType[];
-
-constexpr char Description::Path::Language[];
-constexpr char Description::Path::Text[];
-
-constexpr char IFormula::Path::Dependson[];
-constexpr char IFormula::Path::Modeltype[];
-
-constexpr char IIdentifiable::Path::Administration[];
-constexpr char IIdentifiable::Path::Identification[];
-
-constexpr char IReferenceElement::Path::Modeltype[];
-
-constexpr char IRelationshipElement::Path::First[];
-constexpr char IRelationshipElement::Path::Second[];
-constexpr char IRelationshipElement::Path::ModelType[];
-
-constexpr char ISubmodelElementCollection::Path::AllowDuplicates[];
-constexpr char ISubmodelElementCollection::Path::Ordered[];
-constexpr char ISubmodelElementCollection::Path::ModelType[];
-
-constexpr char IKey::Path::IdType[];
-constexpr char IKey::Path::Local[];
-constexpr char IKey::Path::Type[];
-constexpr char IKey::Path::Value[];
-
-constexpr char IdentifierType::Custom[];
-constexpr char IdentifierType::IRDI[];
-constexpr char IdentifierType::URI[];
-
-
-
-constexpr char IBlob::Path::Value[];
-constexpr char IBlob::Path::MIMEType[];
-
-
-constexpr char IDataSpecificationIEC61360::Path::Definition[];
-constexpr char IDataSpecificationIEC61360::Path::LevelType[];
-constexpr char IDataSpecificationIEC61360::Path::ValueId[];
-constexpr char IDataSpecificationIEC61360::Path::SourceOfDefinition[];
-constexpr char IDataSpecificationIEC61360::Path::ShortName[];
-constexpr char IDataSpecificationIEC61360::Path::ValueFormat[];
-constexpr char IFile::Path::MIMEType[];
-constexpr char IDataSpecificationIEC61360::Path::UnitId[];
-constexpr char IDataSpecificationIEC61360::Path::Unit[];
-constexpr char IDataSpecificationIEC61360::Path::PreferredName[];
-constexpr char IFile::Path::Value[];
-constexpr char IConceptDescription::Path::ModelType[];
-constexpr char IConceptDescription::Path::IsCaseOf[];
-constexpr char IDataSpecification::Path::Content[];
-constexpr char IDataSpecificationIEC61360::Path::ValueList[];
-constexpr char IEntity::Path::EntityType[];
-constexpr char IDataSpecificationIEC61360::Path::DataType[];
-
-
-constexpr char ILangStringSet::Path::Language[];
-constexpr char ILangStringSet::Path::Text[];
-
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/api/dataspecification/datatypes/DataTypeIEC61360.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/api/dataspecification/datatypes/DataTypeIEC61360.cpp
deleted file mode 100644
index 31bd29d..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/api/dataspecification/datatypes/DataTypeIEC61360.cpp
+++ /dev/null
@@ -1,51 +0,0 @@
-#include <BaSyx/submodel/api/dataspecification/datatypes/DataTypeIEC61360.h>
-
-#include <unordered_map>
-#include <string>
-
-#include <BaSyx/util/util.h>
-
-using namespace basyx::submodel;
-
-static const std::string DataTypeIEC61360_to_string[] =
-{
-	"Date",
-	"String",
-	"String_Translatable",
-	"Real_Measure",
-	"Real_Count",
-	"Real_Currency",
-	"Boolean",
-	"Url",
-	"Rational",
-	"Rational_Measure",
-	"Time",
-	"Timestamp"
-};
-
-static const std::unordered_map<std::string, basyx::submodel::DataTypeIEC61360> string_to_DataTypeIEC61360
-{
-	{DataTypeIEC61360_to_string[static_cast<char>(DataTypeIEC61360::Date)], DataTypeIEC61360::Date},
-	{DataTypeIEC61360_to_string[static_cast<char>(DataTypeIEC61360::String)], DataTypeIEC61360::String},
-	{DataTypeIEC61360_to_string[static_cast<char>(DataTypeIEC61360::String_Translatable)], DataTypeIEC61360::String_Translatable},
-	{DataTypeIEC61360_to_string[static_cast<char>(DataTypeIEC61360::Real_Measure)], DataTypeIEC61360::Real_Measure},
-	{DataTypeIEC61360_to_string[static_cast<char>(DataTypeIEC61360::Real_Count)], DataTypeIEC61360::Real_Count},
-	{DataTypeIEC61360_to_string[static_cast<char>(DataTypeIEC61360::Real_Currency)], DataTypeIEC61360::Real_Currency},
-	{DataTypeIEC61360_to_string[static_cast<char>(DataTypeIEC61360::Boolean)], DataTypeIEC61360::Boolean},
-	{DataTypeIEC61360_to_string[static_cast<char>(DataTypeIEC61360::Url)], DataTypeIEC61360::Url},
-	{DataTypeIEC61360_to_string[static_cast<char>(DataTypeIEC61360::Rational)], DataTypeIEC61360::Rational},
-	{DataTypeIEC61360_to_string[static_cast<char>(DataTypeIEC61360::Rational_Measure)], DataTypeIEC61360::Rational_Measure},
-	{DataTypeIEC61360_to_string[static_cast<char>(DataTypeIEC61360::Time)], DataTypeIEC61360::Time},
-	{DataTypeIEC61360_to_string[static_cast<char>(DataTypeIEC61360::Timestamp)], DataTypeIEC61360::Timestamp}
-};
-
-const std::string & util::to_string(basyx::submodel::DataTypeIEC61360 type)
-{
-	return DataTypeIEC61360_to_string[static_cast<char>(type)];
-}
-
-template<>
-basyx::submodel::DataTypeIEC61360 util::from_string<basyx::submodel::DataTypeIEC61360>(const std::string & str)
-{
-	return string_to_DataTypeIEC61360.at(str);
-}
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/api/dataspecification/datatypes/LevelType.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/api/dataspecification/datatypes/LevelType.cpp
deleted file mode 100644
index e3bfc57..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/api/dataspecification/datatypes/LevelType.cpp
+++ /dev/null
@@ -1,35 +0,0 @@
-#include <BaSyx/submodel/api/dataspecification/datatypes/LevelType.h>
-
-#include <unordered_map>
-#include <string>
-
-#include <BaSyx/util/util.h>
-
-using namespace basyx::submodel;
-
-static const std::string LevelType_to_string[4] =
-{
-	"Min",
-	"Max",
-	"Nom",
-	"Typ"
-};
-
-static const std::unordered_map<std::string, basyx::submodel::LevelType> string_to_LevelType
-{
-	{LevelType_to_string[static_cast<char>(LevelType::Min)], LevelType::Min},
-	{LevelType_to_string[static_cast<char>(LevelType::Max)], LevelType::Max},
-	{LevelType_to_string[static_cast<char>(LevelType::Nom)], LevelType::Nom},
-	{LevelType_to_string[static_cast<char>(LevelType::Typ)], LevelType::Typ}
-};
-
-const std::string & util::to_string(basyx::submodel::LevelType levelType)
-{
-	return LevelType_to_string[static_cast<char>(levelType)];
-}
-
-template<>
-basyx::submodel::LevelType util::from_string<basyx::submodel::LevelType>(const std::string & str)
-{
-	return string_to_LevelType.at(str);
-}
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/ConnectedElement.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/ConnectedElement.cpp
deleted file mode 100644
index 054a591..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/ConnectedElement.cpp
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * ConnectedElement.cpp
- *
- *      Author: wendel
- */
-
-#include <BaSyx/submodel/connected/ConnectedElement.h>
-#include <BaSyx/submodel/api/qualifier/IReferable.h>
-
-namespace basyx {
-namespace submodel {
-
-ConnectedElement::ConnectedElement(const std::shared_ptr<vab::core::proxy::IVABElementProxy> & proxy) :
-  proxy(proxy),
-  local_map(new basyx::object::object_map_t)
-{}
-
-ConnectedElement::ConnectedElement(const std::shared_ptr<vab::core::proxy::IVABElementProxy>& proxy, std::shared_ptr<basyx::object::object_map_t> & local_values) :
-  proxy(proxy),
-  local_map(local_values)
-{}
-
-std::shared_ptr<vab::core::proxy::IVABElementProxy> ConnectedElement::getProxy() const
-{
-  return this->proxy;
-}
-
-basyx::object ConnectedElement::getLocalValue(const std::string & path) const 
-{
-  auto element_ptr = this->local_map->find(path);
-  if ( element_ptr != this->local_map->end() )
-    return element_ptr->second;
-  return basyx::object(nullptr);
-}
-
-void ConnectedElement::setLocalValue(const std::string & path, const basyx::object & value)
-{
-  this->local_map->emplace(path, value);
-}
-
-void ConnectedElement::setLocalValues(const basyx::object::object_map_t & values)
-{
-  for ( auto & val : values )
-  {
-    this->local_map->emplace(val.first, val.second);
-  }
-}
-
-void ConnectedElement::updateLocalValue(const std::string & path, const basyx::object value)
-{
-  this->local_map->operator[](path) = value;
-}
-
-
-void ConnectedElement::setId(const std::string & id)
-{
-  this->setProxyValue(IReferable::Path::IdShort, id);
-}
-
-std::string ConnectedElement::getId() const
-{
-  return this->getProxyValue(IReferable::Path::IdShort);
-}
-
-
-void ConnectedElement::setProxyValue(const std::string & path, const basyx::object value) const
-{
-  this->getProxy()->updateElementValue(path, value);
-}
-
-std::string ConnectedElement::getProxyValue(const std::string & path) const
-{
-  auto value = getProxy()->readElementValue(path);
-  return value.Get<std::string>();
-}
-
-std::shared_ptr<basyx::object::object_map_t> ConnectedElement::getProxyMap(const std::string & path) const
-{
-  auto value = getProxy()->readElementValue(path);
-  return std::make_shared<basyx::object::object_map_t>(value.Get<basyx::object::object_map_t>());
-}
-
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/ConnectedSubmodel.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/ConnectedSubmodel.cpp
deleted file mode 100644
index c0f5765..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/ConnectedSubmodel.cpp
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * ConnectedSubmodel.cpp
- *
- *      Author: wendel
- */
-
-#include <BaSyx/submodel/connected/ConnectedSubmodel.h>
-
-#include <BaSyx/submodel/connected/submodelelement/operation/ConnectedOperation.h>
-#include <BaSyx/submodel/connected/submodelelement/property/ConnectedSingleProperty.h>
-#include <BaSyx/submodel/connected/submodelelement/property/ConnectedPropertyFactory.h>
-#include <BaSyx/vab/core/util/VABPath.h>
-#include <BaSyx/submodel/map/qualifier/AdministrativeInformation.h>
-#include <BaSyx/submodel/map/identifier/Identifier.h>
-#include <BaSyx/submodel/map/reference/Reference.h>
-#include <BaSyx/submodel/connected/submodelelement/property/ConnectedProperty.h>
-
-namespace basyx {
-namespace submodel {
-
-std::shared_ptr<IReference> ConnectedSubmodel::getSemanticId() const
-{
-  return std::make_shared<Reference>(*this->getProxyMap(IReference::Path::ReferencePath));
-}
-
-std::shared_ptr<IAdministrativeInformation> ConnectedSubmodel::getAdministration() const
-{
-  return std::make_shared<AdministrativeInformation>(*this->getProxyMap(IAdministrativeInformation::Path::AdministrationPath));
-}
-
-std::shared_ptr<IIdentifier> ConnectedSubmodel::getIdentification() const
-{
-  return std::make_shared<Identifier>(*this->getProxyMap(IIdentifier::Path::IdentifierPath));
-}
-
-basyx::specificCollection_t<IReference> ConnectedSubmodel::getDataSpecificationReferences() const
-{
-  AdministrativeInformation administrative_information(*this->getProxyMap(IAdministrativeInformation::Path::AdministrationPath));
-  return administrative_information.getDataSpecificationReferences();
-}
-
-Kind ConnectedSubmodel::getHasKindReference() const
-{
-  //todo
-  return Kind::NotSpecified;
-}
-
-void ConnectedSubmodel::setDataElements(const basyx::specificMap_t<IProperty> & properties)
-{}
-
-void ConnectedSubmodel::setOperations(const basyx::specificMap_t<IOperation> & operations)
-{}
-
-std::string ConnectedSubmodel::getIdShort() const
-{
-  return this->getProxyValue(IReferable::Path::IdShort);
-}
-
-std::string ConnectedSubmodel::getCategory() const
-{
-  return this->getProxyValue(IReferable::Path::Category);
-}
-
-Description ConnectedSubmodel::getDescription() const
-{
-  return Description(*this->getProxyMap(IReferable::Path::Description));
-}
-
-std::shared_ptr<IReference> ConnectedSubmodel::getParent() const
-{
-  return std::make_shared<Reference>(*this->getProxyMap(IReferable::Path::Parent));
-}
-
-void ConnectedSubmodel::addSubModelElement(const std::shared_ptr<ISubmodelElement> & element)
-{
-  // Todo: May need a wrapper?
-  //this->getProxy()->createElement(SubmodelPaths::SUBMODELELEMENT, element);
-
-  //if ( dynamic_cast<IDataElement*>(element.get()) != nullptr )
-  //{
-  //  this->getProxy()->createElement(SubmodelPaths::PROPERTIES, element);
-  //}
-  //else if ( dynamic_cast<operation::IOperation*>(element.get()) != nullptr )
-  //{
-  //  this->getProxy()->createElement(SubmodelPaths::OPERATIONS, element);
-  //}
-}
-
-basyx::specificMap_t<IDataElement> ConnectedSubmodel::getDataElements() const
-{
-  basyx::specificMap_t<IDataElement> map;
-  auto operations = this->getProxy()->readElementValue(Path::DataElements).Get<basyx::object::object_list_t>();
-
-  for ( auto & operation : operations )
-  {
-    auto data_element_map = operation.Get<basyx::object::object_map_t>();
-    auto id = data_element_map.at(IReferable::Path::IdShort).GetStringContent();
-
-    vab::core::VABPath path(Path::Operations);
-    path = path + id;
-    auto connected_property =
-      backend::connected::support::ConnectedPropertyFactory::createProperty(this->getProxy()->getDeepProxy(path));
-
-  //todo  map.emplace( id, std::dynamic_pointer_cast<IDataElement>(connected_property) );
-  }
-
-  return map;
-}
-
-basyx::specificMap_t<IOperation> ConnectedSubmodel::getOperations() const
-{
-  basyx::specificMap_t<IOperation> map;
-  auto operations = this->getProxy()->readElementValue(Path::Operations).Get<basyx::object::object_list_t>();
-
-  for ( auto & operation : operations )
-  {
-    auto operation_map = operation.Get<basyx::object::object_map_t>();
-    auto id = operation_map.at(IReferable::Path::IdShort).GetStringContent();
-
-    vab::core::VABPath path(Path::Operations);
-    path = path + id;
-    auto connected_operation = std::make_shared<ConnectedOperation>(this->getProxy()->getDeepProxy(path));
-    connected_operation->setLocalValues(operation_map);
-
-    map.emplace(id, connected_operation);
-  }
-
-  return map;
-}
-
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/ConnectedVABModelMap.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/ConnectedVABModelMap.cpp
deleted file mode 100644
index 7a943ba..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/ConnectedVABModelMap.cpp
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * ConnectedVABModelMap.cpp
- *
- *      Author: wendel
- */
-
-#include <BaSyx/submodel/connected/ConnectedVABModelMap.h>
-
-namespace basyx {
-namespace submodel {
-namespace backend {
-
-ConnectedVABModelMap::ConnectedVABModelMap(std::shared_ptr<vab::core::proxy::IVABElementProxy> proxy) :
-  ConnectedElement(proxy)
-{}
-
-}
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/submodelelement/ConnectedDataElement.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/submodelelement/ConnectedDataElement.cpp
deleted file mode 100644
index a1daf74..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/submodelelement/ConnectedDataElement.cpp
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * ConnectedDataElement.cpp
- *
- *      Author: wendel
- */
-
-#include <BaSyx/submodel/connected/submodelelement/ConnectedDataElement.h>
-#include <BaSyx/shared/types.h>
-
-#include <memory>
-
-
-namespace basyx {
-namespace submodel {
-
-ConnectedDataElement::ConnectedDataElement(std::shared_ptr<vab::core::proxy::IVABElementProxy> proxy) :
-  ConnectedSubmodelElement(proxy)
-{}
-
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/submodelelement/ConnectedRelationshipElement.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/submodelelement/ConnectedRelationshipElement.cpp
deleted file mode 100644
index d1a2743..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/submodelelement/ConnectedRelationshipElement.cpp
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * ConnectedRelationshipElement.cpp
- *
- *      Author: wendel
- */
-
-#include <BaSyx/submodel/connected/submodelelement/ConnectedRelationshipElement.h>
-
-namespace basyx {
-namespace submodel {
-
-ConnectedRelationshipElement::ConnectedRelationshipElement(std::shared_ptr<vab::core::proxy::IVABElementProxy> proxy) :
-  ConnectedSubmodelElement(proxy)
-{}
-
-void ConnectedRelationshipElement::setFirst(const IReference & first)
-{
-  //todo
-  //this->setProxyValue(submodelelement::RelationshipElementPath::FIRST, first);
-}
-
-std::shared_ptr<IReference> ConnectedRelationshipElement::getFirst() const
-{
-  //todo
-  return nullptr;// this->getProxyValue(submodelelement::RelationshipElementPath::FIRST);
-}
-
-void ConnectedRelationshipElement::setSecond(const IReference & second)
-{
-  //todo
-  //this->setProxyValue(submodelelement::RelationshipElementPath::SECOND, second);
-}
-
-std::shared_ptr<IReference> ConnectedRelationshipElement::getSecond() const
-{
-  //todo
-  return nullptr;// this->getProxyValue(submodelelement::RelationshipElementPath::SECOND);
-}
-
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/submodelelement/ConnectedSubmodelElement.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/submodelelement/ConnectedSubmodelElement.cpp
deleted file mode 100644
index 9aa081f..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/submodelelement/ConnectedSubmodelElement.cpp
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * ConnectedSubmodelElement.cpp
- *
- *      Author: wendel
- */
-
-#include <BaSyx/submodel/connected/submodelelement/ConnectedSubmodelElement.h>
-#include <BaSyx/submodel/connected/ConnectedElement.h>
-#include <BaSyx/submodel/map/reference/Reference.h>
-#include <BaSyx/shared/types.h>
-
-namespace basyx {
-namespace submodel {
-
-ConnectedSubmodelElement::ConnectedSubmodelElement(std::shared_ptr<vab::core::proxy::IVABElementProxy> proxy) :
-  ConnectedElement(proxy)
-{}
-
-basyx::specificCollection_t<IReference> ConnectedSubmodelElement::getDataSpecificationReferences() const
-{
-  auto data_specs = this->getProxyCollection(IReference::IReference::Path::DataSpecifications);
-
-  basyx::specificCollection_t<IReference> specific_data_specs;
-  for ( auto & spec : data_specs )
-  {
-    Reference data_ref(spec.Get<basyx::object::object_map_t>());
-    specific_data_specs.push_back(std::make_shared<Reference>(data_ref));
-  }
-
-  return specific_data_specs;
-}
-
-std::string ConnectedSubmodelElement::getIdShort() const
-{
-  return this->getProxyValue(IReferable::Path::IdShort);
-}
-
-std::string ConnectedSubmodelElement::getCategory() const
-{
-  return this->getProxyValue(IReferable::Path::Category);
-}
-
-Description ConnectedSubmodelElement::getDescription() const
-{
-  return Description(*this->getProxyMap(IReferable::Path::Description));
-}
-
-std::shared_ptr<IReference> ConnectedSubmodelElement::getParent() const
-{
-  return std::make_shared<Reference>(*this->getProxyMap(IReference::Path::Parents));
-}
-
-basyx::specificCollection_t<IConstraint> ConnectedSubmodelElement::getQualifier() const
-{
-  //TODO not implemented
-  return basyx::specificCollection_t<IConstraint>(); 
-}
-
-std::shared_ptr<IReference> ConnectedSubmodelElement::getSemanticId() const
-{
-  return std::make_shared<Reference>(*this->getProxyMap(IReference::Path::SemanticIds));
-}
-
-Kind ConnectedSubmodelElement::getHasKindReference() const
-{
-  //todo
-  return Kind::NotSpecified;
-}
-
-
-basyx::object::object_list_t ConnectedSubmodelElement::getProxyCollection(const std::string & path) const
-{
-  auto value = this->getProxy()->readElementValue(path);
-  return value.Get<basyx::object::object_list_t>();
-}
-
-std::string ConnectedSubmodelElement::getIdWithLocalCheck() const
-{
-  basyx::object localId = this->getLocalValue(IReferable::Path::IdShort);
-  if ( not localId.IsNull() ) {
-    return localId.Get<std::string>();
-  }
-  return this->getIdShort();
-}
-
-void ConnectedSubmodelElement::setIdWithLocalCheck(const std::string & id)
-{
-  auto localId = this->getLocalValue(IReferable::Path::IdShort);
-  if ( not localId.IsNull() ) {
-    this->updateLocalValue(IReferable::Path::IdShort, id);
-    return;
-  }
-  this->setProxyValue(IReferable::Path::IdShort, id);
-}
-
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/submodelelement/ConnectedSubmodelElementCollection.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/submodelelement/ConnectedSubmodelElementCollection.cpp
deleted file mode 100644
index 6919848..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/submodelelement/ConnectedSubmodelElementCollection.cpp
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * ConnectedSubmodelElementCollection.cpp
- *
- *      Author: wendel
- */
-
-#include <BaSyx/submodel/connected/submodelelement/ConnectedSubmodelElementCollection.h>
-#include <BaSyx/submodel/api/submodelelement/property/IProperty.h>
-#include <BaSyx/submodel/api/ISubModel.h>
-
-namespace basyx {
-namespace submodel {
-
-
-ConnectedSubmodelElementCollection::ConnectedSubmodelElementCollection(std::shared_ptr<vab::core::proxy::IVABElementProxy> proxy):
-  ConnectedSubmodelElement(proxy)
-{}
-
-void ConnectedSubmodelElementCollection::setValue(const basyx::specificCollection_t<ISubmodelElement> & value)
-{
-  //todo
-  //this->setProxyValue(property::PropertyPaths::VALUE, value);
-}
-
-basyx::specificCollection_t<ISubmodelElement> ConnectedSubmodelElementCollection::getValue() const
-{
-  //todo 
-  return basyx::specificCollection_t<ISubmodelElement>(); // this->getProxyCollection(property::PropertyPaths::VALUE);
-}
-
-void ConnectedSubmodelElementCollection::setOrdered(const bool & value)
-{
-  this->setProxyValue(ISubmodelElementCollection::Path::Ordered, value);
-}
-
-bool ConnectedSubmodelElementCollection::isOrdered() const
-{
-  auto element = this->getProxy()->readElementValue(ISubmodelElementCollection::Path::Ordered);
-  return element.Get<bool>();
-}
-
-void ConnectedSubmodelElementCollection::setAllowDuplicates(const bool & value)
-{
-  this->setProxyValue(ISubmodelElementCollection::Path::AllowDuplicates, value);
-}
-
-bool ConnectedSubmodelElementCollection::isAllowDuplicates() const
-{
-  auto element = this->getProxy()->readElementValue(ISubmodelElementCollection::Path::AllowDuplicates);
-  return element.Get<bool>();
-}
-
-void ConnectedSubmodelElementCollection::setElements(const basyx::specificMap_t<ISubmodelElement> & elements)
-{
-  //todo 
-  //this->setProxyValue(SubmodelPaths::SUBMODELELEMENT, elements);
-}
-
-basyx::specificMap_t<ISubmodelElement> ConnectedSubmodelElementCollection::getElements() const
-{
-  //todo 
-  
-  //auto elements = this->getProxy()->readElementValue(SubmodelPaths::SUBMODELELEMENT);
-  return basyx::specificMap_t<ISubmodelElement>();
-}
-
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/submodelelement/operation/ConnectedOperation.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/submodelelement/operation/ConnectedOperation.cpp
deleted file mode 100644
index dcf2666..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/submodelelement/operation/ConnectedOperation.cpp
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * ConnectedOperation.cpp
- *
- *      Author: wendel
- */
-
-#include <BaSyx/submodel/connected/submodelelement/operation/ConnectedOperation.h>
-
-namespace basyx {
-namespace submodel {
-
-ConnectedOperation::ConnectedOperation(std::shared_ptr<vab::core::proxy::IVABElementProxy> proxy) :
-  ConnectedSubmodelElement(proxy)
-{}
-
-void ConnectedOperation::setId(const std::string & id)
-{
-  this->setIdWithLocalCheck(id);
-}
-
-std::string ConnectedOperation::getId() const
-{
-  return this->getIdWithLocalCheck();
-}
-
-basyx::specificCollection_t<IOperationVariable> ConnectedOperation::getParameterTypes() const
-{
-  // todo
-  return basyx::specificCollection_t<IOperationVariable>(); // this->getProxyCollection(std::string(submodelelement::operation::OperationPaths::INPUT));
-}
-
-std::shared_ptr<IOperationVariable>ConnectedOperation::getReturnType() const
-{
-  // todo
-  return std::shared_ptr<IOperationVariable>(); // this->getProxyCollection(std::string(submodelelement::operation::OperationPaths::INPUT));
-}
-
-basyx::object ConnectedOperation::invoke(basyx::object & parameters) const
-{
-  return this->getProxy()->invoke("", parameters);
-
-}
-
-basyx::object ConnectedOperation::getInvocable() const
-{
-  // Not supported on remote side.
-  return basyx::detail::functionWrapper();
-}
-
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/submodelelement/property/ConnectedCollectionProperty.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/submodelelement/property/ConnectedCollectionProperty.cpp
deleted file mode 100644
index 13cb50b..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/submodelelement/property/ConnectedCollectionProperty.cpp
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * ConnectedCollectionProperty.cpp
- *
- *      Author: wendel
- */
-
-#include <BaSyx/submodel/connected/submodelelement/property/ConnectedCollectionProperty.h>
-#include <BaSyx/submodel/api/submodelelement/property/IProperty.h>
-
-namespace basyx {
-namespace submodel {
-
-using namespace submodelelement::property;
-
-ConnectedCollectionProperty::ConnectedCollectionProperty(std::shared_ptr<vab::core::proxy::IVABElementProxy> proxy) :
-  ConnectedProperty(PropertyType::Collection, proxy)
-{}
-
-void ConnectedCollectionProperty::set(const basyx::object::object_list_t & collection) const
-{
-  this->getProxy()->updateElementValue(IProperty::Path::Value, collection);
-}
-
-void ConnectedCollectionProperty::add(const basyx::object & newValue)
-{
-  this->getProxy()->createElement(IProperty::Path::Value, newValue);
-}
-
-void ConnectedCollectionProperty::remove(basyx::object & objectRef)
-{
-  this->getProxy()->deleteElement(IProperty::Path::Value, objectRef);
-}
-
-basyx::object::object_list_t ConnectedCollectionProperty::getElements() const
-{
-  return this->retrieveObject().Get<basyx::object::object_list_t>();
-}
-
-int ConnectedCollectionProperty::getElementCount() const
-{
-  return this->retrieveObject().Get<basyx::object::object_list_t>().size();
-}
-
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/submodelelement/property/ConnectedMapProperty.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/submodelelement/property/ConnectedMapProperty.cpp
deleted file mode 100644
index 14619f8..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/submodelelement/property/ConnectedMapProperty.cpp
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * ConnectedMapProperty.cpp
- *
- *      Author: wendel
- */
-
-#include <BaSyx/submodel/connected/submodelelement/property/ConnectedMapProperty.h>
-#include <BaSyx/vab/core/util/VABPath.h>
-
-namespace basyx {
-namespace submodel {
-
-using namespace submodelelement::property;
-
-ConnectedMapProperty::ConnectedMapProperty(std::shared_ptr<vab::core::proxy::IVABElementProxy> proxy) :
-  ConnectedProperty(PropertyType::Map, proxy)
-{}
-
-basyx::object ConnectedMapProperty::getValue(const std::string & key) const
-{
-  return this->getMap().at(key);
-}
-
-void ConnectedMapProperty::put(const std::string & key, const basyx::object & value) const
-{
-  basyx::vab::core::VABPath path(IProperty::Path::Value);
-  path.append(key);
-  this->setProxyValue(path, value);
-}
-
-void ConnectedMapProperty::set( const basyx::object::object_map_t & map ) const
-{
-  this->setProxyValue(IProperty::Path::Value, map);
-}
-
-basyx::object::object_list_t ConnectedMapProperty::getKeys() const
-{
-  auto map = this->getMap();
-  basyx::object::object_list_t keys;
-  keys.reserve(map.size());
-
-  for ( auto entry : map ) {
-    keys.push_back(entry.first);
-  }
-
-  return keys;
-}
-
-int ConnectedMapProperty::getEntryCount() const 
-{
-  return this->getMap().size();
-}
-
-void ConnectedMapProperty::remove(const std::string & key) const
-{
-  basyx::vab::core::VABPath path(IProperty::Path::Value);
-  path.append(key);
-  this->getProxy()->deleteElement(path);
-}
-
-basyx::object::object_map_t ConnectedMapProperty::getMap() const
-{
-  auto map = this->getProxy()->readElementValue(IProperty::Path::Value).Get<basyx::object::object_map_t>();
-  return map;
-}
-
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/submodelelement/property/ConnectedProperty.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/submodelelement/property/ConnectedProperty.cpp
deleted file mode 100644
index 0b804de..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/submodelelement/property/ConnectedProperty.cpp
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * ConnectedProperty.cpp
- *
- *      Author: wendel
- */
-#include <BaSyx/submodel/connected/submodelelement/property/ConnectedProperty.h>
-#include <BaSyx/shared/anyTypeChecker.h>
-
-namespace basyx {
-namespace submodel {
-
-
-ConnectedProperty::ConnectedProperty(PropertyType type, std::shared_ptr<vab::core::proxy::IVABElementProxy> proxy) :
-  ConnectedDataElement(proxy),
-  type(type)
-{}
-
-IProperty::PropertyType ConnectedProperty::getPropertyType() const
-{
-  return this->type;
-}
-
-void ConnectedProperty::setId(const std::string & id)
-{
-  this->setId(id);
-}
-
-std::string ConnectedProperty::getId() const
-{
-  return this->getId();
-}
-
-basyx::object ConnectedProperty::retrieveObject() const
-{
-  return this->getProxy()->readElementValue(IProperty::Path::Value).Get<basyx::object::object_map_t>().at(IProperty::Path::Value);
-}
-
-void ConnectedProperty::setValueId(const std::string & valueId)
-{}
-
-std::string ConnectedProperty::getValueId() const
-{
-  return std::string();
-}
-
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/submodelelement/property/ConnectedReferenceElement.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/submodelelement/property/ConnectedReferenceElement.cpp
deleted file mode 100644
index a3f0c65..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/submodelelement/property/ConnectedReferenceElement.cpp
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * ConnectedReferenceElement.cpp
- *
- *      Author: wendel
- */
-
-#include <BaSyx/submodel/connected/submodelelement/property/ConnectedReferenceElement.h>
-
-namespace basyx {
-namespace submodel {
-
-ConnectedReferenceElement::ConnectedReferenceElement(std::shared_ptr<vab::core::proxy::IVABElementProxy> proxy) :
-  ConnectedDataElement(proxy)
-{}
-
-void ConnectedReferenceElement::setValue(const IReference & ref)
-{
-  //todo
-  //this->setProxyValue(submodelelement::property::PropertyPaths::VALUE, ref);
-}
-
-std::shared_ptr<IReference> ConnectedReferenceElement::getValue() const
-{
-  //todo 
-  return nullptr;// this->getProxyValue(submodelelement::property::PropertyPaths::VALUE);
-}
-
-}
-}
-
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/submodelelement/property/ConnectedSingleProperty.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/submodelelement/property/ConnectedSingleProperty.cpp
deleted file mode 100644
index 64166f1..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/submodelelement/property/ConnectedSingleProperty.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * ConnectedSingleProperty.cpp
- *
- *      Author: wendel
- */
-
-#include <BaSyx/submodel/connected/submodelelement/property/ConnectedSingleProperty.h>
-#include <BaSyx/submodel/api/submodelelement/property/IProperty.h>
-
-namespace basyx {
-namespace submodel {
-
-ConnectedSingleProperty::ConnectedSingleProperty(std::shared_ptr<vab::core::proxy::IVABElementProxy> proxy) :
-  ConnectedProperty(PropertyType::Single, proxy)
-{}
-
-basyx::object ConnectedSingleProperty::get() const
-{
-  return this->retrieveObject();
-}
-
-void ConnectedSingleProperty::set(const basyx::object & value)
-{
-  this->setProxyValue(IProperty::Path::Value, value);
-}
-
-std::string ConnectedSingleProperty::getValueType() const
-{
-  auto map = this->getProxy()->readElementValue("").Get<basyx::object::object_map_t>();
-  return map.at(IProperty::Path::ValueType).Get<std::string>();
-}
-
-void basyx::submodel::ConnectedSingleProperty::setValueId(const std::string & valueId)
-{}
-
-std::string basyx::submodel::ConnectedSingleProperty::getValueId() const
-{
-  return std::string();
-}
-
-IProperty::PropertyType basyx::submodel::ConnectedSingleProperty::getPropertyType() const
-{
-  return PropertyType();
-}
-
-
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/submodelelement/property/blob/ConnectedBlob.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/submodelelement/property/blob/ConnectedBlob.cpp
deleted file mode 100644
index dca591e..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/submodelelement/property/blob/ConnectedBlob.cpp
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * ConnectedBlob.cpp
- *
- *      Author: wendel
- */
-
-#include <BaSyx/submodel/connected/submodelelement/property/blob/ConnectedBlob.h>
-#include <BaSyx/submodel/api/submodelelement/property/IProperty.h>
-
-namespace basyx {
-namespace submodel {
-
-ConnectedBlob::ConnectedBlob(std::shared_ptr<vab::core::proxy::IVABElementProxy> proxy) :
- ConnectedDataElement(proxy)
-{}
-
-void ConnectedBlob::setValue(const std::string & bytes)
-{
-  this->setProxyValue(IProperty::Path::Value, bytes);
-}
-
-const std::string & ConnectedBlob::getValue() const
-{
-  return getProxy()->readElementValue(IProperty::Path::Value).GetStringContent();
-}
-
-void ConnectedBlob::setMimeType(const std::string & mimeType)
-{
-  this->setProxyValue(IBlob::Path::MIMEType, mimeType);
-}
-
-const std::string & ConnectedBlob::getMimeType() const
-{
-  return this->getProxyValue(IBlob::Path::MIMEType);
-}
-
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/submodelelement/property/file/ConnectedFile.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/submodelelement/property/file/ConnectedFile.cpp
deleted file mode 100644
index 2502005..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/connected/submodelelement/property/file/ConnectedFile.cpp
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * ConnectedFile.cpp
- *
- *      Author: wendel
- */
-
-#include <BaSyx/submodel/connected/submodelelement/property/file/ConnectedFile.h>
-#include <BaSyx/submodel/api/submodelelement/property/IProperty.h>
-#include <BaSyx/submodel/api/submodelelement/property/blob/IBlob.h>
-
-namespace basyx {
-namespace submodel {
-
-ConnectedFile::ConnectedFile(std::shared_ptr<vab::core::proxy::IVABElementProxy> proxy) :
-  ConnectedDataElement(proxy)
-{}
-
-void ConnectedFile::setValue(const std::string & value)
-{
-	this->setProxyValue(IProperty::Path::Value, value);
-}
-
-const std::string & ConnectedFile::getValue() const
-{
-	return this->getProxyValue(IProperty::Path::Value);
-}
-
-void ConnectedFile::setMimeType(const std::string & mimeType)
-{
-	this->setProxyValue(IBlob::Path::MIMEType, mimeType);
-}
-
-const std::string & ConnectedFile::getMimeType() const
-{
-	return this->getProxyValue(IBlob::Path::MIMEType);
-}
-
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/enumerations/IdentifiableElements.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/enumerations/IdentifiableElements.cpp
index 295fb35..374072f 100644
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/enumerations/IdentifiableElements.cpp
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/enumerations/IdentifiableElements.cpp
@@ -9,26 +9,12 @@
 
 using enum_pair_t = std::pair<const char*, IdentifiableElements>;
 
-static const std::array<enum_pair_t, 18> string_to_enum = 
+static const std::array<enum_pair_t, 4> string_to_enum = 
 {
-    std::make_pair("AccessPermissionRule",  IdentifiableElements::AccessPermissionRule),
-    std::make_pair("AnnotatedRelationshipElemenBasicEvent", IdentifiableElements::AnnotatedRelationshipElemenBasicEvent),
-    std::make_pair("Blob", IdentifiableElements::Blob),
-    std::make_pair("Capability", IdentifiableElements::Capability),
-    std::make_pair("ConceptDictionary", IdentifiableElements::ConceptDictionary),
-    std::make_pair("DataElement", IdentifiableElements::DataElement),
-    std::make_pair("Entity", IdentifiableElements::Entity),
-    std::make_pair("Event", IdentifiableElements::Event),
-    std::make_pair("File", IdentifiableElements::File),
-    std::make_pair("MultiLanguageProperty", IdentifiableElements::MultiLanguageProperty),
-    std::make_pair("Operation", IdentifiableElements::Operation),
-    std::make_pair("Property", IdentifiableElements::Property),
-    std::make_pair("Range", IdentifiableElements::Range),
-    std::make_pair("ReferenceElement", IdentifiableElements::ReferenceElement),
-    std::make_pair("RelationshipElement", IdentifiableElements::RelationshipElement),
-    std::make_pair("SubmodelElement", IdentifiableElements::SubmodelElement),
-    std::make_pair("SubmodelElementCollection", IdentifiableElements::SubmodelElementCollection),
-    std::make_pair("View", IdentifiableElements::View),
+    std::make_pair("Asset",  IdentifiableElements::Asset),
+    std::make_pair("AssetAdministrationShell", IdentifiableElements::AssetAdministrationShell),
+    std::make_pair("ConceptDescription", IdentifiableElements::ConceptDescription),
+    std::make_pair("Submodel", IdentifiableElements::Submodel),
 };
 
 IdentifiableElements IdentifiableElements_::from_string(const std::string & name)
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/enumerations/IdentifierType.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/enumerations/IdentifierType.cpp
index 0d1261f..a33dfc1 100644
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/enumerations/IdentifierType.cpp
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/enumerations/IdentifierType.cpp
@@ -1,3 +1,5 @@
+#ifdef IDENT_TYPE
+
 #include <BaSyx/submodel/enumerations/IdentifierType.h>
 
 #include <array>
@@ -37,3 +39,4 @@
     return pair->first;
 }
 
+#endif
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/enumerations/KeyElements.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/enumerations/KeyElements.cpp
index 8871f43..14cdf84 100644
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/enumerations/KeyElements.cpp
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/enumerations/KeyElements.cpp
@@ -9,7 +9,7 @@
 
 using enum_pair_t = std::pair<const char*, KeyElements>;
 
-static const std::array<enum_pair_t, 26> string_to_enum = 
+static const std::array<enum_pair_t, 27> string_to_enum = 
 {
     std::make_pair("GlobalReference",  KeyElements::GlobalReference),
     std::make_pair("FragmentReference", KeyElements::FragmentReference),
@@ -25,6 +25,7 @@
     std::make_pair("File", KeyElements::File),
     std::make_pair("MultiLanguageProperty", KeyElements::MultiLanguageProperty),
     std::make_pair("Operation", KeyElements::Operation),
+    std::make_pair("OperationVariable", KeyElements::OperationVariable),
     std::make_pair("Property", KeyElements::Property),
     std::make_pair("Range", KeyElements::Range),
     std::make_pair("ReferenceElement", KeyElements::ReferenceElement),
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/SubModel.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/SubModel.cpp
deleted file mode 100644
index d7f0983..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/SubModel.cpp
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * SubModel.cpp
- *
- *      Author: wendel
- */
-
-#include <BaSyx/submodel/map/SubModel.h>
-#include <BaSyx/submodel/map/submodelelement/operation/Operation.h>
-#include <BaSyx/submodel/map/submodelelement/property/Property.h>
-
-namespace basyx {
-namespace submodel {
-
-    SubModel::SubModel(
-        const IHasSemantics& semantics,
-        const IIdentifiable& identifiable,
-        const IQualifiable& qualifiable,
-        const IHasDataSpecification& specification,
-        const IHasKind& hasKind)
-        : vab::ElementMap {}
-        , ModelType { ISubModel::Path::ModelType }
-        , HasSemantics { semantics }
-        , Identifiable { identifiable }
-        , Qualifiable { qualifiable }
-        , HasDataSpecification { specification }
-        , HasKind { hasKind }
-    {
-        this->map.insertKey(ISubModel::Path::Operations, basyx::object::make_map());
-        this->map.insertKey(ISubModel::Path::DataElements, basyx::object::make_map());
-        this->map.insertKey(ISubModel::Path::Submodelelement, basyx::object::make_map());
-    }
-
-    //SubModel::SubModel(const basyx::object& object)
-    //    : vab::ElementMap { object }
-    //    , ModelType { ISubModel::Path::ModelType }
-    //{
-    //    //todo: may assert if all sufficient parent classes are in object
-    //}
-
-    SubModel::SubModel()
-        : SubModel {
-            HasSemantics {},
-            Identifiable {},
-            Qualifiable {},
-            HasDataSpecification {},
-            HasKind {}
-        }
-    {
-    }
-
-    SubModel::SubModel(const ISubModel& submodel)
-        : SubModel {
-            HasSemantics { submodel.getSemanticId() },
-            Identifiable { *submodel.getIdentification(), *submodel.getAdministration() },
-            Qualifiable { submodel.getQualifier() },
-            HasDataSpecification { submodel.getDataSpecificationReferences() },
-            HasKind { submodel.getHasKindReference() }
-        }
-    {
-    }
-
-    void SubModel::setDataElements(const basyx::specificMap_t<IDataElement>& dataElements)
-    {
-        basyx::object map = basyx::object::make_map();
-        for ( auto & elem : dataElements )
-        {
-          auto obj = DataElement{*elem.second}.getMap();
-          map.insertKey(elem.first, obj, true);
-        }
-        this->map.insertKey(ISubModel::Path::DataElements, map, true);
-    }
-
-    void SubModel::setOperations(const basyx::specificMap_t<IOperation>& operations)
-    {
-        basyx::object map = basyx::object::make_map();
-        for (auto& elem : operations) {
-            auto obj = Operation { *elem.second }.getMap();
-            map.insertKey(elem.first, obj, true);
-        }
-        this->map.insertKey(ISubModel::Path::Operations, map, true);
-    }
-
-    void SubModel::addSubModelElement(const std::shared_ptr<ISubmodelElement>& element)
-    {
-        //SubmodelElement element_obj { element };
-        //this->map.getProperty(ISubModel::Path::Submodelelement).insertKey(element->getIdShort(), element_obj.getMap());
-    }
-
-    basyx::specificMap_t<IDataElement> SubModel::getDataElements() const
-    {
-        basyx::specificMap_t<IDataElement> specific_map;
-        auto & obj_map = this->map.getProperty(ISubModel::Path::DataElements).Get<object::object_map_t&>();
-        for (auto& elem : obj_map) 
-		{
-            auto submodel_elem = std::make_shared<DataElement>(elem.second);
-			specific_map.emplace(elem.first, submodel_elem);
-        }
-
-        return specific_map;
-    }
-
-    void SubModel::addOperation(const IOperation& operation)
-    {
-		auto operations = this->getMap().getProperty(ISubModel::Path::Operations);
-		Operation operation_obj{ operation };
-		operations.insertKey(operation.getIdShort(), operation_obj.getMap() );
-    }
-
-    void SubModel::addDataElement(const IDataElement& dataElement)
-    {
-		auto dataElements = this->getMap().getProperty(ISubModel::Path::DataElements);
-		DataElement dataElement_obj{ dataElement };
-		dataElements.insertKey(dataElement.getIdShort(), dataElement_obj.getMap());
-    }
-
-    basyx::specificMap_t<IOperation> SubModel::getOperations() const
-    {
-        basyx::specificMap_t<IOperation> specific_map;
-        auto & obj_map = this->map.getProperty(ISubModel::Path::Operations).Get<object::object_map_t&>();
-        for (auto& elem : obj_map) 
-		{
-            auto submodel_elem = std::make_shared<Operation>(elem.second);
-            specific_map.emplace(elem.first, submodel_elem);
-        }
-
-        return specific_map;
-    }
-
-	basyx::specificMap_t<ISubmodelElement> SubModel::getSubmodelElements() const
-	{
-		basyx::specificMap_t<ISubmodelElement> specific_map;
-		auto & obj_map = this->map.getProperty(ISubModel::Path::Submodelelement).Get<object::object_map_t&>();
-		for (auto& elem : obj_map)
-		{
-			auto submodel_elem = std::make_shared<SubmodelElement>(elem.second);
-			specific_map.emplace(elem.first, submodel_elem);
-		}
-
-		return specific_map;
-	}
-
-
-}
-}
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/dataspecification/DataSpecification.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/dataspecification/DataSpecification.cpp
deleted file mode 100644
index 6cff6e3..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/dataspecification/DataSpecification.cpp
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * DataSpecification.cpp
- *
- *      Author: wendel
- */
-
-#include <BaSyx/submodel/map/dataspecification/DataSpecification.h>
-#include <BaSyx/submodel/map/dataspecification/DataSpecificationContent.h>
-
-namespace basyx {
-namespace submodel {
-
-DataSpecification::DataSpecification(basyx::object obj)
-  : vab::ElementMap(obj)
-{}
-
-std::shared_ptr<IDataSpecificationContent> DataSpecification::getContent() const
-{
-  return std::make_shared<DataSpecificationContent>(this->map.getProperty(IDataSpecification::Path::Content));
-}
-
-void DataSpecification::setContent(const std::shared_ptr<IDataSpecificationContent>& content)
-{
-  this->map.insertKey(IDataSpecification::Path::Content, DataSpecificationContent(*content).getMap());
-}
-
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/dataspecification/DataSpecificationContent.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/dataspecification/DataSpecificationContent.cpp
deleted file mode 100644
index 89217bc..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/dataspecification/DataSpecificationContent.cpp
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * DataSpecificationContent.cpp
- *
- *      Author: wendel
- */
-
-#include <BaSyx/submodel/map/dataspecification/DataSpecificationContent.h>
-
-namespace basyx {
-namespace submodel {
-
-DataSpecificationContent::DataSpecificationContent(const IDataSpecificationContent & other)
-  : vab::ElementMap()
-{
-}
-
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/dataspecification/DataSpecificationIEC61360.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/dataspecification/DataSpecificationIEC61360.cpp
deleted file mode 100644
index 6f85672..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/dataspecification/DataSpecificationIEC61360.cpp
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * DataSpecificationIEC61360.cpp
- *
- *      Author: wendel
- */
-
-#include <BaSyx/submodel/map/dataspecification/DataSpecificationIEC61360.h>
-#include <BaSyx/submodel/map/reference/Reference.h>
-#include <BaSyx/submodel/map/submodelelement/langstring/LangStringSet.h>
-
-namespace basyx {
-namespace submodel {
-
-DataSpecificationIEC61360::DataSpecificationIEC61360()
-{
-	this->map.insertKey(IDataSpecificationIEC61360::Path::PreferredName, LangStringSet().getMap());
-	this->map.insertKey(IDataSpecificationIEC61360::Path::ShortName, LangStringSet().getMap());
-	this->map.insertKey(IDataSpecificationIEC61360::Path::Definition, LangStringSet().getMap());
-}
-
-std::shared_ptr<ILangStringSet> DataSpecificationIEC61360::PreferredName()
-{
-	auto langStringObj = this->map.getProperty(IDataSpecificationIEC61360::Path::PreferredName);
-	return std::make_shared<LangStringSet>(langStringObj);
-}
-
-std::shared_ptr<ILangStringSet> DataSpecificationIEC61360::ShortName()
-{
-	auto langStringObj = this->map.getProperty(IDataSpecificationIEC61360::Path::ShortName);
-	return std::make_shared<LangStringSet>(langStringObj);
-}
-
-std::string DataSpecificationIEC61360::getUnit() const
-{
-	return this->map.getProperty(IDataSpecificationIEC61360::Path::Unit).GetStringContent();
-}
-
-std::shared_ptr<submodel::IReference> DataSpecificationIEC61360::getUnitId() const
-{
-	return std::make_shared<submodel::Reference>(this->map.getProperty(IDataSpecificationIEC61360::Path::UnitId));
-}
-
-std::string DataSpecificationIEC61360::getSourceOfDefinition() const
-{
-	return this->map.getProperty(IDataSpecificationIEC61360::Path::SourceOfDefinition).GetStringContent();
-}
-
-DataTypeIEC61360 DataSpecificationIEC61360::getDataType() const
-{
-	const auto & dataTypeStr = this->map.getProperty(IDataSpecificationIEC61360::Path::DataType).GetStringContent();
-	return util::from_string<DataTypeIEC61360>(dataTypeStr);
-}
-
-std::shared_ptr<ILangStringSet> DataSpecificationIEC61360::Definition()
-{
-	auto langStringObj = this->map.getProperty(IDataSpecificationIEC61360::Path::Definition);
-	return std::make_shared<LangStringSet>(langStringObj);
-}
-
-std::string DataSpecificationIEC61360::getValueFormat() const
-{
-  return this->map.getProperty(IDataSpecificationIEC61360::Path::ValueFormat).GetStringContent();
-}
-
-basyx::object DataSpecificationIEC61360::getValueList() const
-{
-  return this->map.getProperty(IDataSpecificationIEC61360::Path::ValueList).GetStringContent();
-}
-
-std::shared_ptr<submodel::IReference> DataSpecificationIEC61360::getValueId() const
-{
-  return std::make_shared<submodel::Reference>(this->map.getProperty(IDataSpecificationIEC61360::Path::ValueId));
-}
-
-LevelType DataSpecificationIEC61360::getLevelType() const
-{
-  return util::from_string<LevelType>(this->map.getProperty(IDataSpecificationIEC61360::Path::LevelType).GetStringContent());
-}
-
-void DataSpecificationIEC61360::setUnit(const std::string & unit)
-{
-  this->map.insertKey(IDataSpecificationIEC61360::Path::Unit, unit);
-}
-
-void DataSpecificationIEC61360::setUnitId(const IReference & unitId)
-{
-  this->map.insertKey(IDataSpecificationIEC61360::Path::UnitId, submodel::Reference(unitId).getMap());
-}
-
-void DataSpecificationIEC61360::setSourceOfDefinition(const std::string & sourceOfDefinition)
-{
-  this->map.insertKey(IDataSpecificationIEC61360::Path::SourceOfDefinition, sourceOfDefinition);
-}
-
-void DataSpecificationIEC61360::setDataType(const std::string & dataType)
-{
-  this->map.insertKey(IDataSpecificationIEC61360::Path::DataType, dataType);
-}
-
-void DataSpecificationIEC61360::setValueFormat(const std::string & valueFormat)
-{
-  this->map.insertKey(IDataSpecificationIEC61360::Path::ValueFormat, valueFormat);
-}
-
-void DataSpecificationIEC61360::setValueList(const basyx::object & valueList)
-{
-  this->map.insertKey(IDataSpecificationIEC61360::Path::ValueList, valueList);
-}
-
-void DataSpecificationIEC61360::setValueId(const submodel::IReference & valueId)
-{
-  this->map.insertKey(IDataSpecificationIEC61360::Path::ValueId, submodel::Reference(valueId).getMap());
-}
-
-//void DataSpecificationIEC61360::setLevelType(const std::string & levelType)
-//{
-//  this->map.insertKey(IDataSpecificationIEC61360::Path::LevelType, levelType);
-//}
-
-void DataSpecificationIEC61360::setLevelType(const LevelType & levelType)
-{
-	this->map.insertKey(IDataSpecificationIEC61360::Path::LevelType, util::to_string(levelType), true);
-}
-
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/identifier/Identifier.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/identifier/Identifier.cpp
deleted file mode 100644
index 174a2c9..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/identifier/Identifier.cpp
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Identifier.cpp
- *
- *      Author: wendel
- */
-
-#include <BaSyx/submodel/map/identifier/Identifier.h>
-#include <BaSyx/submodel/map/identifier/IdentifierType.h>
-
-namespace basyx {
-namespace submodel {
-
-Identifier::Identifier()
-  : vab::ElementMap {}
-{
-  this->map.insertKey(Path::Id, "");
-  this->map.insertKey(Path::IdType, "");
-}
-
-Identifier::Identifier(const std::string & id, const std::string & idType)
-  : vab::ElementMap {}
-{
-  this->map.insertKey(Path::Id, id);
-  this->map.insertKey(Path::IdType, idType);
-}
-
-Identifier::Identifier(basyx::object object)
-  :vab::ElementMap {object}
-{}
-
-Identifier::Identifier(const std::shared_ptr<IIdentifier>& other)
-  : Identifier {other->getId(), other->getIdType()}
-{}
-
-Identifier::Identifier(const IIdentifier & other)
-  : Identifier {other.getId(), other.getIdType()}
-{}
-
-std::string Identifier::getIdType() const
-{
-  return this->map.getProperty(Path::IdType).GetStringContent();
-}
-
-std::string Identifier::getId() const
-{
-  return this->map.getProperty(Path::Id).GetStringContent();
-}
-
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/modeltype/ModelType.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/modeltype/ModelType.cpp
deleted file mode 100644
index 507def8..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/modeltype/ModelType.cpp
+++ /dev/null
@@ -1,20 +0,0 @@
-#include <BaSyx/submodel/map/modeltype/ModelType.h>
-
-basyx::submodel::ModelType::ModelType()
-	: vab::ElementMap{}
-{
-	this->map.insertKey(Path::Name, "");
-	this->map.insertKey(Path::ModelType, basyx::object::make_map());
-}
-
-//basyx::submodel::ModelType::ModelType(basyx::object object)
-//	: vab::ElementMap{object}
-//{
-//}
-
-basyx::submodel::ModelType::ModelType(const std::string & type)
-	: vab::ElementMap{}
-{
-	this->map.insertKey(Path::ModelType, basyx::object::make_map());
-	this->map.getProperty(Path::ModelType).insertKey(Path::Name, type);
-};
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/parts/ConceptDescription.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/parts/ConceptDescription.cpp
deleted file mode 100644
index 5f943da..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/parts/ConceptDescription.cpp
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * ConceptDictionary.cpp
- *
- *      Author: wendel
- */
-
-#include <BaSyx/submodel/map/parts/ConceptDescription.h>
-
-#include <BaSyx/submodel/map/reference/Reference.h>
-
-using namespace basyx::submodel;
-
-namespace basyx {
-namespace submodel {
-
-ConceptDescription::ConceptDescription(basyx::object obj)
-  : vab::ElementMap(obj)
-{}
-
-ConceptDescription::ConceptDescription()
-  : vab::ElementMap()
-  , submodel::ModelType(IConceptDescription::Path::ModelType)
-{}
-
-ConceptDescription::ConceptDescription(IConceptDescription & other)
-  : vab::ElementMap()
-  , submodel::ModelType(IConceptDescription::Path::ModelType)
-{
-  this->setIsCaseOf(other.getIsCaseOf());
-}
-
-
-basyx::specificCollection_t<IReference> ConceptDescription::getIsCaseOf() const
-{
-  auto description_objects = this->map.getProperty(IConceptDescription::Path::IsCaseOf).Get<basyx::object::object_list_t>();
-  return vab::ElementMap::make_specific_collection<IReference, Reference>(description_objects);  
-}
-
-void ConceptDescription::setIsCaseOf(const basyx::specificCollection_t<IReference>& references)
-{
-  auto description_objects = vab::ElementMap::make_object_list<IReference, Reference>(references);
-  this->map.insertKey(IConceptDescription::Path::IsCaseOf, description_objects);
-}
-
-}
-}
-
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/qualifier/AdministrativeInformation.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/qualifier/AdministrativeInformation.cpp
deleted file mode 100644
index 255d38c..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/qualifier/AdministrativeInformation.cpp
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * AdministrativeInformation.cpp
- *
- *      Author: wendel
- */
-
-#include <BaSyx/submodel/map/qualifier/AdministrativeInformation.h>
-
-namespace basyx {
-namespace submodel {
-
-AdministrativeInformation::AdministrativeInformation()
-	: HasDataSpecification{}
-  , vab::ElementMap {}
-{
-	this->map.insertKey(IAdministrativeInformation::Path::Version, "");
-	this->map.insertKey(IAdministrativeInformation::Path::Revision, "");
-}
-
-AdministrativeInformation::AdministrativeInformation(const std::string & version, const std::string & revision)
-	: HasDataSpecification{}
-  , vab::ElementMap{}
-{
-	this->map.insertKey(IAdministrativeInformation::Path::Version, version);
-	this->map.insertKey(IAdministrativeInformation::Path::Revision, revision);
-}
-
-AdministrativeInformation::AdministrativeInformation(basyx::object obj)
-	: vab::ElementMap{obj}
-{
-}
-
-AdministrativeInformation::AdministrativeInformation(const IAdministrativeInformation & other)
-  : vab::ElementMap {}
-{
-  this->setDataSpecificationReferences(other.getDataSpecificationReferences());
-  this->setRevision(other.getRevision());
-  this->setVersion(other.getVersion());
-}
-
-void AdministrativeInformation::setVersion(const std::string & version)
-{
-	this->map.insertKey(IAdministrativeInformation::Path::Version, version, true);
-}
-
-void AdministrativeInformation::setRevision(const std::string & revision)
-{
-	this->map.insertKey(IAdministrativeInformation::Path::Revision, revision, true);
-}
-
-std::string AdministrativeInformation::getVersion() const
-{
-	return this->map.getProperty(IAdministrativeInformation::Path::Version).GetStringContent();
-}
-
-std::string AdministrativeInformation::getRevision() const
-{
-	return this->map.getProperty(IAdministrativeInformation::Path::Revision).GetStringContent();
-}
-
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/qualifier/Description.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/qualifier/Description.cpp
deleted file mode 100644
index 8a735e2..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/qualifier/Description.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Description.cpp
- *
- *      Author: wendel
- */
-
-#include <BaSyx/submodel/map/qualifier/Description.h>
-
-
-namespace basyx {
-namespace submodel {
-
-Description::Description()
-	: vab::ElementMap{}
-{
-	this->map.insertKey(Path::Language, "");
-	this->map.insertKey(Path::Text, "");
-};
-
-Description::Description(const std::string & language, const std::string & text)
-	: vab::ElementMap{}
-{
-	this->map.insertKey(Path::Language, language);
-	this->map.insertKey(Path::Text, text);
-}
-
-Description::Description(basyx::object object)
-	: vab::ElementMap{ object }
-{
-}
-
-std::string Description::getLanguage() const
-{
-  return this->map.getProperty(Path::Language).GetStringContent();
-}
-
-std::string Description::getText() const
-{
-	return this->map.getProperty(Path::Text).GetStringContent();
-}
-
-bool operator==(const Description & left, const Description & right)
-{
-  return (left.getLanguage() == right.getLanguage()) and (left.getText() == right.getText());
-}
-
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/qualifier/HasDataSpecification.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/qualifier/HasDataSpecification.cpp
deleted file mode 100644
index 3633fbc..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/qualifier/HasDataSpecification.cpp
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * HasDataSpecification.cpp
- *
- *      Author: wendel
- */
-
-#include <BaSyx/submodel/map/qualifier/HasDataSpecification.h>
-
-#include <BaSyx/submodel/map/reference/Reference.h>
-
-namespace basyx {
-namespace submodel {
-
-HasDataSpecification::HasDataSpecification()
-	: vab::ElementMap{}
-{
-	this->map.insertKey(Path::HasDataSpecification, basyx::object::make_list<basyx::object>());
-}
-
-HasDataSpecification::HasDataSpecification(basyx::object & obj)
-	: vab::ElementMap{obj}
-{
-
-}
-
-HasDataSpecification::HasDataSpecification(const basyx::specificCollection_t<IReference>& refs)
-	: vab::ElementMap{}
-{
-	this->setDataSpecificationReferences(refs);
-}
-
-HasDataSpecification::HasDataSpecification(const IHasDataSpecification & hasDataSpecification)
-  : vab::ElementMap{}
-{
-  this->setDataSpecificationReferences(hasDataSpecification.getDataSpecificationReferences());
-}
-
-basyx::specificCollection_t<IReference> HasDataSpecification::getDataSpecificationReferences() const
-{
-	auto obj_list = this->map.getProperty(Path::HasDataSpecification).Get<basyx::object::object_list_t&>();
-	return vab::ElementMap::make_specific_collection<IReference, Reference>(obj_list);
-}
-
-void HasDataSpecification::setDataSpecificationReferences(const basyx::specificCollection_t<IReference> & references)
-{
-	auto list = basyx::object::make_list<basyx::object>();
-
-	for (const auto & ref : references)
-	{
-		Reference reference{ ref->getKeys() };
-		list.insert(reference.getMap());
-	};
-
-	this->map.insertKey(Path::HasDataSpecification, list, true);
-}
-
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/qualifier/HasKind.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/qualifier/HasKind.cpp
deleted file mode 100644
index 84989da..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/qualifier/HasKind.cpp
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * HasKind.cpp
- *
- *      Author: wendel
- */
-
-#include <BaSyx/submodel/map/qualifier/HasKind.h>
-
-using namespace basyx::submodel;
-
-HasKind::HasKind(Kind kind) 
-	: vab::ElementMap()
-{
-	this->Init(kind);
-}
-
-void HasKind::Init(Kind kind)
-{
-	this->map.insertKey(Path::Kind, util::to_string(kind));
-};
-
-HasKind::HasKind(basyx::object object)
-	: vab::ElementMap(object)
-{
-}
-
-basyx::submodel::HasKind::HasKind(const IHasKind & other) :
-  vab::ElementMap{}
-{
-  this->setHasKindReference(other.getHasKindReference());
-}
-
-Kind HasKind::getHasKindReference() const
-{
-	return util::from_string<Kind>(this->map.getProperty(Path::Kind).GetStringContent());
-}
-
-void HasKind::setHasKindReference(Kind kind)
-{
-	this->map.insertKey(Path::Kind, util::to_string(kind), true);
-}
-
-static const std::string kind_to_string[] = {
-	"NotSpecified",
-	"Type",
-	"Instance"
-};
-
-static const std::unordered_map<std::string, Kind> string_to_kind{
-	{ kind_to_string[static_cast<char>(Kind::Instance)] , Kind::Instance },
-	{ kind_to_string[static_cast<char>(Kind::Type)] , Kind::Type },
-	{ kind_to_string[static_cast<char>(Kind::NotSpecified)] , Kind::NotSpecified }
-};
-
-const std::string & util::to_string(Kind kind)
-{
-	return kind_to_string[static_cast<char>(kind)];
-}
-
-template<>
-Kind util::from_string<Kind>(const std::string & str)
-{
-	return string_to_kind.at(str);
-};
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/qualifier/HasSemantics.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/qualifier/HasSemantics.cpp
deleted file mode 100644
index e113237..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/qualifier/HasSemantics.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * HasSemantics.cpp
- *
- *      Author: wendel
- */
-
-#include <BaSyx/submodel/map/qualifier/HasSemantics.h>
-#include <BaSyx/submodel/map/reference/Reference.h>
-
-namespace basyx {
-namespace submodel {
-
-
-HasSemantics::HasSemantics()
-	: vab::ElementMap{}
-{
-	this->map.insertKey(Path::SemanticId, Reference{}.getMap());
-}
-
-HasSemantics::HasSemantics(basyx::object object)
-	: vab::ElementMap{object}
-{}
-
-HasSemantics::HasSemantics(const std::shared_ptr<IReference>& reference) 
-	: vab::ElementMap{}
-{
-	this->setSemanticId(reference);
-}
-
-HasSemantics::HasSemantics(const IHasSemantics & semantics) :
-  vab::ElementMap{}
-{
-  this->setSemanticId(semantics.getSemanticId());
-}
-
-std::shared_ptr<IReference> HasSemantics::getSemanticId() const
-{
-	return std::make_shared<Reference>(this->map.getProperty(Path::SemanticId));
-}
-
-void HasSemantics::setSemanticId(const std::shared_ptr<IReference> & reference)
-{
-	Reference ref{ reference->getKeys() };
-	this->map.insertKey(Path::SemanticId, ref.getMap(), true);
-}
-
-void HasSemantics::setSemanticId(const IReference & reference)
-{
-	Reference ref{ reference.getKeys() };
-	this->map.insertKey(Path::SemanticId, ref.getMap(), true);
-}
-
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/qualifier/Identifiable.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/qualifier/Identifiable.cpp
deleted file mode 100644
index 405c4cd..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/qualifier/Identifiable.cpp
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Identifiable.cpp
- *
- *      Author: wendel
- */
-
-#include <BaSyx/submodel/map/qualifier/Identifiable.h>
-
-#include <BaSyx/submodel/map/qualifier/AdministrativeInformation.h>
-#include <BaSyx/submodel/map/identifier/Identifier.h>
-
-namespace basyx {
-namespace submodel {
-
-
-Identifiable::Identifiable() :
-  vab::ElementMap{},
-  Referable{}
-{
-  this->setIdentification(Identifier {"", ""});
-  this->setAdministration(AdministrativeInformation {"", ""});
-}
-
-Identifiable::Identifiable(const basyx::object & obj) :
-  vab::ElementMap{obj}
-{}
-
-Identifiable::Identifiable(const IIdentifiable & identifiable) :
-  vab::ElementMap{},
-  Referable{identifiable.getIdShort(), identifiable.getCategory(), identifiable.getDescription()}
-{  
-  this->setParent(*identifiable.getParent());
-  this->setAdministration(*identifiable.getAdministration());
-  this->setIdentification(*identifiable.getIdentification());
-}
-
-Identifiable::Identifiable(const IIdentifier & identifier, const IAdministrativeInformation & administration)
-	: vab::ElementMap{}
-	, Referable{}
-{
-	this->setIdentification(identifier);
-	this->setAdministration(administration);
-};
-
-Identifiable::Identifiable(
-	const std::string & version, 
-	const std::string & revision, 
-	const std::string & idShort, 
-	const std::string & category, 
-	const Description & description, 
-	const std::string & idType, 
-	const std::string & id) 
-    : Referable{idShort, category, description}
-{
-  this->setIdentification(Identifier{id, idType});
-  this->setAdministration(AdministrativeInformation {version, revision});
-}
-
-std::shared_ptr<IAdministrativeInformation> Identifiable::getAdministration() const
-{
-	return std::make_shared<AdministrativeInformation>(this->map.getProperty(IIdentifiable::Path::Administration));
-}
-
-std::shared_ptr<IIdentifier> Identifiable::getIdentification() const
-{
-  return std::make_shared<Identifier>(this->map.getProperty(IIdentifiable::Path::Identification));
-}
-
-void Identifiable::setAdministration(const IAdministrativeInformation & administration)
-{
-  this->insertMapElement(IIdentifiable::Path::Administration, AdministrativeInformation(administration));
-}
-
-void Identifiable::setIdentification(const IIdentifier & identification)
-{
-  this->insertMapElement(IIdentifiable::Path::Identification, Identifier(identification));
-}
-
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/qualifier/Referable.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/qualifier/Referable.cpp
deleted file mode 100644
index ec0675f..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/qualifier/Referable.cpp
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Referable.cpp
- *
- *      Author: wendel
- */
-
-#include <BaSyx/submodel/map/qualifier/Referable.h>
-#include <BaSyx/submodel/map/reference/Reference.h>
-
-namespace basyx {
-namespace submodel {
-
-Referable::Referable()
-  : vab::ElementMap{}
-{
-	this->map.insertKey(Path::IdShort, "");
-	this->map.insertKey(Path::Category, "");
-	this->map.insertKey(Path::Description, basyx::object::make_map());
-	this->map.insertKey(Path::Parent, Reference{}.getMap());
-}
-
-basyx::submodel::Referable::Referable(basyx::object & obj)
-	: vab::ElementMap{ obj }
-{
-	this->map.insertKey(Path::IdShort, "");
-	this->map.insertKey(Path::Category, "");
-	this->map.insertKey(Path::Description, Description{}.getMap());
-	this->map.insertKey(Path::Parent, Reference{}.getMap());
-}
-
-Referable::Referable(const std::string & idShort, const std::string & category, const Description & description) :
-  vab::ElementMap{}
-{
-	this->map.insertKey(Path::IdShort, idShort, true);
-	this->map.insertKey(Path::Category, category, true);
-	this->map.insertKey(Path::Description, description.getMap(), true);
-  this->map.insertKey(Path::Parent, Reference{}.getMap(), true);
-}
-
-Referable::Referable(const IReferable & other) :
-  vab::ElementMap{}
-{
-  this->setIdShort(other.getIdShort());
-  this->setCategory(other.getCategory());
-  this->setDescription(other.getDescription());
-  this->setParent(*other.getParent());
-}
-
-std::string Referable::getIdShort() const
-{
-	return this->map.getProperty(Path::IdShort).GetStringContent();
-}
-
-std::string Referable::getCategory() const
-{
-	return this->map.getProperty(Path::Category).GetStringContent();
-}
-
-Description Referable::getDescription() const
-{
-	return Description{ this->map.getProperty(Path::Description) };
-}
-
-std::shared_ptr<IReference> Referable::getParent() const
-{
-	return std::make_shared<Reference>(this->map.getProperty(Path::Parent));
-}
-
-void Referable::setIdShort(const std::string & shortID)
-{
-	this->map.insertKey(Path::IdShort, shortID, true);
-}
-
-void Referable::setCategory(const std::string & category)
-{
-	this->map.insertKey(Path::Category, category, true);
-}
-
-void Referable::setDescription(const Description & description)
-{
-	this->map.insertKey(Path::Description, description.getMap(), true);
-}
-
-void Referable::setParent(const IReference & parentReference)
-{
-  this->insertMapElement(Path::Parent, Reference{parentReference});
-}
-
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/qualifier/qualifiable/Constraint.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/qualifier/qualifiable/Constraint.cpp
deleted file mode 100644
index 3783173..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/qualifier/qualifiable/Constraint.cpp
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Constraint.cpp
- *
- *      Author: wendel
- */
-
-#include <BaSyx/submodel/map/qualifier/qualifiable/Constraint.h>
-
-#include <BaSyx/submodel/map/modeltype/ModelType.h>
-
-namespace basyx {
-namespace submodel {
-
-Constraint::Constraint()
-  : vab::ElementMap {ModelType(std::string(Path::ModelType)).getMap()}
-{}
-
-Constraint::Constraint(basyx::object object)
-  : vab::ElementMap {object}
-{}
-
-Constraint::Constraint(const IConstraint & constraint)
-  : vab::ElementMap {ModelType(std::string(Path::ModelType)).getMap()}
-{}
-
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/qualifier/qualifiable/Formula.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/qualifier/qualifiable/Formula.cpp
deleted file mode 100644
index 2497dc6..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/qualifier/qualifiable/Formula.cpp
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Formula.cpp
- *
- *      Author: wendel
- */
-
-#include <BaSyx/submodel/map/qualifier/qualifiable/Formula.h>
-#include <BaSyx/submodel/map/reference/Reference.h>
-#include <BaSyx/submodel/map/modeltype/ModelType.h>
-
-
-namespace basyx {
-namespace submodel {
-
-
-Formula::Formula() :
-  vab::ElementMap{ModelType(std::string(IFormula::Path::Modeltype)).getMap()}
-{
-  this->map.insertKey(IFormula::Path::Dependson, basyx::object::make_list<basyx::object>()); 
-}
-
-Formula::Formula(const basyx::specificCollection_t<IReference>& dependsOn) :
-  vab::ElementMap{ModelType(std::string(IFormula::Path::Modeltype)).getMap()}
-{
-  this->setDependsOn(dependsOn);
-}
-
-basyx::specificCollection_t<IReference> Formula::getDependsOn() const
-{
-  auto & obj_list = this->map.getProperty(IFormula::Path::Dependson).Get<basyx::object::object_list_t&>();
-  return vab::ElementMap::make_specific_collection<IReference, Reference>(obj_list);
-}
-
-void Formula::setDependsOn(const basyx::specificCollection_t<IReference>& dependsOn)
-{
-  auto obj_list = vab::ElementMap::make_object_list<IReference, Reference>(dependsOn);
-  this->map.insertKey(IFormula::Path::Dependson, obj_list, true);
-}
-
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/qualifier/qualifiable/Qualifiable.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/qualifier/qualifiable/Qualifiable.cpp
deleted file mode 100644
index fd31d33..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/qualifier/qualifiable/Qualifiable.cpp
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Qualifiable.cpp
- *
- *      Author: wendel
- */
-
-#include <BaSyx/submodel/map/qualifier/qualifiable/Qualifiable.h>
-
-#include <BaSyx/submodel/map/qualifier/qualifiable/Constraint.h>
-
-namespace basyx {
-namespace submodel {
-
-Qualifiable::Qualifiable()
-	: vab::ElementMap{}
-{
-	this->map.insertKey(Path::Constraints, basyx::object::make_list<basyx::object>());
-}
-
-Qualifiable::Qualifiable(const std::shared_ptr<IQualifiable> & other)
-  : Qualifiable{other->getQualifier()}
-{}
-
-Qualifiable::Qualifiable(const IQualifiable & other)
-  : vab::ElementMap{}
-{
-  this->setQualifier(other.getQualifier());
-}
-
-Qualifiable::Qualifiable(basyx::object object)
-	: vab::ElementMap{object}
-{
-  this->map.insertKey(Path::Constraints, basyx::object::make_list<basyx::object>(), false); 
-}
-
-Qualifiable::Qualifiable(const std::shared_ptr<IConstraint>& constraint)
-	: vab::ElementMap{}
-{
-	Constraint con{ *constraint };
-	auto list = basyx::object::make_list<basyx::object>();
-	list.insert(con.getMap());
-	this->map.insertKey(Path::Constraints, list);
-}
-
-Qualifiable::Qualifiable(const basyx::specificCollection_t<IConstraint> & constraints)
-	: vab::ElementMap{}
-{
-	this->setQualifier(constraints);
-}
-
-basyx::specificCollection_t<IConstraint> Qualifiable::getQualifier() const
-{
-  auto list = this->map.getProperty(Path::Constraints).Get<basyx::object::object_list_t>();
-	return vab::ElementMap::make_specific_collection<IConstraint, Constraint>(list);
-}
-
-void Qualifiable::setQualifier(const basyx::specificCollection_t<IConstraint>& qualifiers)
-{
-	auto list = vab::ElementMap::make_object_list<IConstraint, Constraint>(qualifiers);
-	map.insertKey(Path::Constraints, list, true);
-}
-
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/qualifier/qualifiable/Qualifier.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/qualifier/qualifiable/Qualifier.cpp
deleted file mode 100644
index e86280f..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/qualifier/qualifiable/Qualifier.cpp
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Qualifier.cpp
- *
- *      Author: wendel
- */
-
-#include <BaSyx/submodel/map/qualifier/qualifiable/Qualifier.h>
-#include <BaSyx/submodel/map/reference/Reference.h>
-#include <BaSyx/submodel/map/modeltype/ModelType.h>
-
-namespace basyx {
-namespace submodel {
-
-Qualifier::Qualifier() :
-  vab::ElementMap{ModelType{IQualifier::Path::Modeltype}}
-{
-  this->setQualifierType("Type not specified");
-}
-
-Qualifier::Qualifier(
-	  const std::string & qualifierType, 
-	  const basyx::object & qualifierValue, 
-	  const IReference & valueId) 
-  : vab::ElementMap{ModelType{IQualifier::Path::Modeltype}}
-{
-  this->setQualifierType(qualifierType);
-  this->setQualifierValue(qualifierValue);
-  this->setQualifierValueId(valueId);
-}
-
-std::string Qualifier::getQualifierType() const
-{
-  return this->map.getProperty(IQualifier::Path::QualifierType).GetStringContent();
-}
-
-basyx::object Qualifier::getQualifierValue() const
-{
-  return this->map.getProperty(IQualifier::Path::QualifierValue);
-}
-
-std::shared_ptr<IReference> Qualifier::getQualifierValueId() const
-{
-  return std::make_shared<Reference>(this->map.getProperty(IQualifier::Path::QualifierValueID));
-}
-
-void Qualifier::setQualifierType(const std::string & qualifierType)
-{
-  this->map.insertKey(IQualifier::Path::QualifierType, qualifierType, true);
-}
-
-void Qualifier::setQualifierValue(const basyx::object & qualifierValue)
-{
-  this->map.insertKey(IQualifier::Path::QualifierValue, qualifierValue, true);
-}
-
-void Qualifier::setQualifierValueId(const IReference & valueId)
-{
-  Reference reference{valueId};
-  this->insertMapElement(IQualifier::Path::QualifierValueID, reference);
-}
-
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/qualifier/qualifiable/QualifierType.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/qualifier/qualifiable/QualifierType.cpp
deleted file mode 100644
index 3f74a98..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/qualifier/qualifiable/QualifierType.cpp
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
- * QualifierType.cpp
- *
- *      Author: wendel
- */
-
-#include <BaSyx/submodel/map/qualifier/qualifiable/QualifierType.h>
-
-namespace basyx {
-namespace submodel {
-
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/reference/Key.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/reference/Key.cpp
deleted file mode 100644
index eddf516..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/reference/Key.cpp
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Key.cpp
- *
- *      Author: wendel
- */
-
-#include <BaSyx/submodel/map/reference/Key.h>
-
-#include <BaSyx/shared/object.h>
-
-#include <BaSyx/vab/ElementMap.h>
-
-namespace basyx {
-namespace submodel {
-
-	constexpr char Key::KeyElements::ConceptDictionary[];
-
-
-Key::Key(const std::string & type, const bool & local, const std::string & value, const std::string & idType)
-	: vab::ElementMap{}
-{
-	this->setType(type);
-	this->setLocal(local);
-	this->setValue(value);
-	this->setIdType(idType);
-}
-
-Key::Key(basyx::object obj)
-  : vab::ElementMap(obj)
-{};
-
-std::string Key::getType() const
-{
-	return map.getProperty(IKey::Path::Type).GetStringContent();
-}
-
-bool Key::isLocal() const
-{
-	return map.getProperty(IKey::Path::Local).Get<bool>();
-}
-
-std::string Key::getValue() const
-{
-	return map.getProperty(IKey::Path::Value).GetStringContent();
-}
-
-std::string Key::getidType() const
-{
-	return map.getProperty(IKey::Path::IdType).GetStringContent();
-}
-
-void Key::setType(const std::string & type)
-{
-	map.insertKey(IKey::Path::Type, type, true);
-}
-
-void Key::setLocal(const bool & local)
-{
-	map.insertKey(IKey::Path::Local, local, true);
-}
-
-void Key::setValue(const std::string & value)
-{
-	map.insertKey(IKey::Path::Value, value, true);
-}
-
-void Key::setIdType(const std::string & idType)
-{
-	map.insertKey(IKey::Path::IdType, idType, true);
-}
-
-bool operator==(const IKey & left, const IKey & right)
-{
-  return (left.getidType() == right.getidType()) and (left.getValue() == right.getValue()) and (left.getType() == right.getType()) and (left.isLocal() == right.isLocal());
-}
-
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/reference/Reference.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/reference/Reference.cpp
deleted file mode 100644
index 1610ff3..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/reference/Reference.cpp
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Reference.cpp
- *
- *      Author: wendel
- */
-
-#include <BaSyx/submodel/map/reference/Reference.h>
-
-#include <BaSyx/submodel/map/reference/Key.h>
-
-namespace basyx {
-namespace submodel {
-
-Reference::Reference() 
-	: vab::ElementMap{}
-{
-	this->setKeys(basyx::specificCollection_t<IKey>());
-}
-
-Reference::Reference(const basyx::specificCollection_t<IKey> & keys)
-	: vab::ElementMap{}
-{
-	this->setKeys(keys);
-}
-
-Reference::Reference(const std::initializer_list<Key> keys)
-	: vab::ElementMap{}
-{
-	auto list = basyx::object::make_list<basyx::object>();
-
-	for (auto & key : keys)
-	{
-		list.insert(key.getMap());
-	}
-
-	map.insertKey(IReference::Path::Key, list, true);
-}
-
-Reference::Reference(const IReference & reference) :
-  vab::ElementMap{}
-{
-  this->setKeys(reference.getKeys());
-}
-
-const basyx::specificCollection_t<IKey> Reference::getKeys() const
-{
-	auto & obj_list = this->map.getProperty(IReference::Path::Key).Get<basyx::object::object_list_t&>();
-	basyx::specificCollection_t<IKey> keys;
-
-	for (auto & obj : obj_list)
-	{
-		keys.emplace_back(std::make_shared<Key>(obj));
-	};
-
-	return keys;
-}
-
-void Reference::setKeys(const basyx::specificCollection_t<IKey>& keys)
-{
-	auto list = basyx::object::make_list<basyx::object>();
-
-	for (auto & key : keys)
-	{
-		Key newKey{
-			key->getType(),
-			key->isLocal(),
-			key->getValue(),
-			key->getidType()
-		};
-
-		list.insert(newKey.getMap());
-	}
-	map.insertKey(IReference::Path::Key, list, true);
-}
-
-Reference Reference::FromIdentifiable(const std::string & keyElementType, bool local, const IIdentifiable & identifiable)
-{
-	Key key{ keyElementType, local, identifiable.getIdentification()->getId(), identifiable.getIdentification()->getIdType() };
-	return Reference{ key };
-}
-
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/submodelelement/DataElement.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/submodelelement/DataElement.cpp
deleted file mode 100644
index 3a2c46f..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/submodelelement/DataElement.cpp
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * DataElement.cpp
- *
- *      Author: wendel
- */
-
-#include <BaSyx/submodel/map/submodelelement/DataElement.h>
-
-namespace basyx {
-namespace submodel {
-
-DataElement::DataElement() :
-  vab::ElementMap{},
-  ModelType{IDataElement::Path::ModelType}
-{}
-
-DataElement::DataElement(basyx::object object) :
-  vab::ElementMap{object},
-	ModelType{ IDataElement::Path::ModelType }
-{}
-
-DataElement::DataElement(const IDataElement & other) :
-  SubmodelElement{other},
-	ModelType{ IDataElement::Path::ModelType }
-{}
-
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/submodelelement/ReferenceElement.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/submodelelement/ReferenceElement.cpp
deleted file mode 100644
index 6c6250f..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/submodelelement/ReferenceElement.cpp
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * ReferenceElement.cpp
- *
- *      Author: wendel
- */
-
-#include <BaSyx/submodel/map/submodelelement/ReferenceElement.h>
-#include <BaSyx/submodel/map/reference/Reference.h>
-
-namespace basyx {
-namespace submodel {
-
-ReferenceElement::ReferenceElement() :
-  vab::ElementMap{},
-  ModelType{IReferenceElement::Path::Modeltype}
-{}
-
-ReferenceElement::ReferenceElement(const IReference & reference) :
-  vab::ElementMap{},
-  ModelType{IReferenceElement::Path::Modeltype}
-{
-  this->setValue(reference);
-}
-
-ReferenceElement::ReferenceElement(const basyx::object & map) :
-  vab::ElementMap{map}
-{}
-
-void ReferenceElement::setValue(const IReference & ref)
-{
-  Reference reference {ref};
-  this->insertMapElement(IProperty::Path::Value, reference);
-}
-
-std::shared_ptr<IReference> ReferenceElement::getValue() const
-{
-  return std::make_shared<Reference>(this->map.getProperty(IProperty::Path::Value));
-}
-
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/submodelelement/RelationshipElement.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/submodelelement/RelationshipElement.cpp
deleted file mode 100644
index e04fa81..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/submodelelement/RelationshipElement.cpp
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * RelationshipElement.cpp
- *
- *      Author: wendel
- */
-
-#include <BaSyx/submodel/map/submodelelement/RelationshipElement.h>
-#include <BaSyx/submodel/map/reference/Reference.h>
-
-namespace basyx {
-namespace submodel {
-
-RelationshipElement::RelationshipElement() :
-  vab::ElementMap {},
-  ModelType{IRelationshipElement::Path::ModelType}
-{}
-
-RelationshipElement::RelationshipElement(const IReference & first, const IReference & second) :
-  vab::ElementMap{},
-  ModelType {IRelationshipElement::Path::ModelType}
-{
-  this->setFirst(first);
-  this->setSecond(second);
-}
-
-void RelationshipElement::setFirst(const IReference& first)
-{
-  Reference ref {first};
-  this->insertMapElement(IRelationshipElement::Path::First, ref);
-}
-
-std::shared_ptr<IReference> RelationshipElement::getFirst() const
-{
-  return std::make_shared<Reference>(this->map.getProperty(IRelationshipElement::Path::First));
-}
-
-void RelationshipElement::setSecond(const IReference& second)
-{
-  Reference ref {second};
-  this->insertMapElement(IRelationshipElement::Path::Second, ref);
-}
-
-std::shared_ptr<IReference> RelationshipElement::getSecond() const
-{
-  return std::make_shared<Reference>(this->map.getProperty(IRelationshipElement::Path::Second));
-}
-
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/submodelelement/SubmodelElement.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/submodelelement/SubmodelElement.cpp
deleted file mode 100644
index 1464883..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/submodelelement/SubmodelElement.cpp
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * SubmodelElement.cpp
- *
- *      Author: wendel
- */
-
-#include <BaSyx/submodel/map/submodelelement/SubmodelElement.h>
-
-namespace basyx {
-namespace submodel {
-
-
-SubmodelElement::SubmodelElement()
-	: vab::ElementMap{}
-	, ModelType(ISubmodelElement::Path::ModelType)
-{}
-
-
-SubmodelElement::SubmodelElement(const ISubmodelElement & abstractSubmodelElement)
-  : vab::ElementMap{}
-  , ModelType{ISubmodelElement::Path::ModelType}
-  , HasDataSpecification{abstractSubmodelElement.getDataSpecificationReferences()}
-  , HasKind{abstractSubmodelElement.getHasKindReference()}
-  , HasSemantics{abstractSubmodelElement.getSemanticId()}
-  , Qualifiable{abstractSubmodelElement.getQualifier()}
-  , Referable{abstractSubmodelElement.getIdShort(), abstractSubmodelElement.getCategory(), abstractSubmodelElement.getDescription()}
-{}
-
-}
-}
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/submodelelement/SubmodelElementCollection.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/submodelelement/SubmodelElementCollection.cpp
deleted file mode 100644
index 5ef72b6..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/submodelelement/SubmodelElementCollection.cpp
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * SubmodelElementCollection.cpp
- *
- *      Author: wendel
- */
-
-#include <BaSyx/submodel/map/submodelelement/SubmodelElementCollection.h>
-#include <BaSyx/submodel/api/submodelelement/property/IProperty.h>
-#include <BaSyx/submodel/api/ISubModel.h>
-
-namespace basyx {
-namespace submodel {
-
-SubmodelElementCollection::SubmodelElementCollection() :
-  vab::ElementMap{},
-  ModelType{ISubmodelElementCollection::Path::ModelType}
-{}
-
-SubmodelElementCollection::SubmodelElementCollection(const basyx::specificCollection_t<ISubmodelElement>& value, const bool ordered, const bool allowDuplicates) :
-  vab::ElementMap{},
-  ModelType{ISubmodelElementCollection::Path::ModelType}
-{
-	this->setValue(value);
-	this->setOrdered(ordered);
-	this->setAllowDuplicates(allowDuplicates);
-}
-
-void SubmodelElementCollection::setValue(const basyx::specificCollection_t<ISubmodelElement> & value)
-{
-  //auto obj_list = vab::ElementMap::make_object_list<ISubmodelElement, SubmodelElement>(value);
-  //this->map.insertKey(IProperty::Path::Value, obj_list);
-}
-
-basyx::specificCollection_t<ISubmodelElement> SubmodelElementCollection::getValue() const
-{
-  basyx::specificCollection_t<ISubmodelElement> list;
-  auto obj_list = this->map.getProperty(IProperty::Path::Value).Get<basyx::object::object_list_t>();
-  for ( auto & elem : obj_list )
-  {
-    list.push_back(std::make_shared<SubmodelElement>(elem));
-  }
-  return list;
-}
-
-void SubmodelElementCollection::setOrdered(const bool & ordered)
-{
-  this->map.insertKey(ISubmodelElementCollection::Path::Ordered, ordered, true);
-}
-
-bool SubmodelElementCollection::isOrdered() const
-{
-  return this->map.getProperty(ISubmodelElementCollection::Path::Ordered).Get<bool>();
-}
-
-void SubmodelElementCollection::setAllowDuplicates(const bool & allowDuplicates)
-{
-  this->map.insertKey(ISubmodelElementCollection::Path::AllowDuplicates, allowDuplicates, true);
-}
-
-bool SubmodelElementCollection::isAllowDuplicates() const
-{
-  return this->map.getProperty(ISubmodelElementCollection::Path::AllowDuplicates).Get<bool>();
-}
-
-void SubmodelElementCollection::setElements(const basyx::specificMap_t<ISubmodelElement> & value)
-{
-  basyx::object map = basyx::object::make_map();
-  for ( auto & elem : value )
-  {
-	auto obj = SubmodelElement{*elem.second}.getMap();
-	map.insertKey(elem.first, obj, true);
-  }
-  this->map.insertKey(ISubModel::Path::Submodelelement, map);
-}
-
-basyx::specificMap_t<ISubmodelElement> SubmodelElementCollection::getElements() const
-{
-  basyx::specificMap_t<ISubmodelElement> specific_map;
-  auto obj_map = this->map.getProperty(ISubModel::Path::Submodelelement).Get<object::object_map_t>();
-  for ( auto & elem : obj_map )
-  {
-    auto submodel_elem = std::make_shared<SubmodelElement>(SubmodelElement{elem.second});
-    specific_map.insert(std::pair<std::string, std::shared_ptr<ISubmodelElement>>(elem.first, submodel_elem));
-  }
-
-  return specific_map;
-}
-
-void SubmodelElementCollection::addSubmodelElement(const ISubmodelElement & element)
-{
-
-}
-
-
-
-}
-}
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/submodelelement/entity/Entity.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/submodelelement/entity/Entity.cpp
deleted file mode 100644
index eb21e2d..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/submodelelement/entity/Entity.cpp
+++ /dev/null
@@ -1,35 +0,0 @@
-#include <BaSyx/submodel/map/submodelelement/entity/Entity.h>
-
-namespace basyx {
-namespace submodel {
-	Entity::Entity(EntityType entityType)
-	{
-		this->map.insertKey(IEntity::Path::EntityType, static_cast<char>(entityType), true);
-	}
-
-	Entity::Entity(basyx::object object)
-		: ElementMap{ object }
-	{
-	}
-
-	Entity::Entity(const IEntity & entity)
-	{
-
-	}
-
-	basyx::specificCollection_t<ISubmodelElement> basyx::submodel::Entity::getStatements()
-	{
-		return specificCollection_t<ISubmodelElement>();
-	}
-
-	EntityType Entity::getEntityType() const
-	{
-		return static_cast<EntityType>(this->map.getProperty(IEntity::Path::EntityType).Get<int>());
-	}
-
-	std::shared_ptr<IReference> Entity::getAsset() const
-	{
-		return std::shared_ptr<IReference>();
-	}
-}
-}
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/submodelelement/langstring/LangStringSet.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/submodelelement/langstring/LangStringSet.cpp
deleted file mode 100644
index 004fc40..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/submodelelement/langstring/LangStringSet.cpp
+++ /dev/null
@@ -1,55 +0,0 @@
-#include <BaSyx/submodel/map/submodelelement/langstring/LangStringSet.h>
-
-const std::string empty{};
-
-basyx::submodel::LangStringSet::LangStringSet()
-	: vab::ElementMap{basyx::object::make_object_list()}
-{
-}
-
-basyx::submodel::LangStringSet::LangStringSet(std::initializer_list<std::pair<std::string, std::string>> il)
-	: LangStringSet()
-{
-	for (const auto & entry : il)
-		this->addLangString(entry.first, entry.second);
-}
-
-const std::string & basyx::submodel::LangStringSet::getLangString(const std::string & languageCode) const
-{
-	auto & objectSet = this->getMap().Get<basyx::object::object_list_t&>();
-
-	for (auto & entry : objectSet)
-	{
-		auto & object = const_cast<basyx::object&>(entry);
-		if (object.getProperty(Path::Language) == languageCode) {
-			return object.getProperty(Path::Text).GetStringContent();
-		}
-	};
-
-	return empty;
-}
-
-basyx::submodel::LangStringSet::langCodeSet_t basyx::submodel::LangStringSet::getLanguageCodes() const
-{
-	auto & objectList = this->getMap().Get<basyx::object::object_list_t&>();
-
-	std::remove_const<langCodeSet_t>::type ret;
-	ret.reserve(objectList.size());
-
-	for (auto & entry : objectList)
-	{
-		auto & object = const_cast<basyx::object&>(entry);
-		ret.emplace_back( std::cref( object.getProperty(Path::Language).GetStringContent()) );
-	};
-
-	return ret;
-};
-
-void basyx::submodel::LangStringSet::addLangString(const std::string & languageCode, const std::string & langString)
-{
-	auto langStringMap = basyx::object::make_map();
-	langStringMap.insertKey( Path::Language, languageCode );
-	langStringMap.insertKey( Path::Text, langString);
-
-	this->map.insert(langStringMap);
-}
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/submodelelement/operation/Operation.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/submodelelement/operation/Operation.cpp
deleted file mode 100644
index a7dac64..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/submodelelement/operation/Operation.cpp
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Operation.cpp
- *
- *      Author: wendel
- */
-
-#include <BaSyx/submodel/map/submodelelement/operation/Operation.h>
-#include <BaSyx/shared/object/obj_function.h>
-
-namespace basyx {
-namespace submodel {
-
-Operation::Operation()
-  : vab::ElementMap{}
-  , ModelType{Path::ModelType}
-  , SubmodelElement{}
-{
-  this->map.insertKey(Path::Input, basyx::object::make_list<basyx::object>());
-  this->map.insertKey(Path::Invokable, basyx::object::make_null());
-  this->map.insertKey(Path::Output, basyx::object::make_null());
-}
-
-Operation::Operation(const IOperation & other)
-  : vab::ElementMap{}
-  , ModelType{Path::ModelType}
-  , SubmodelElement{other}
-{
-  this->setParameterTypes(other.getParameterTypes());
-  this->setReturnTypes(other.getReturnType());
-  this->setInvocable(other.getInvocable());
-}
-
-Operation::Operation(const basyx::object & obj) :
-  vab::ElementMap{obj}
-  , SubmodelElement{}
-{}
-
-basyx::specificCollection_t<IOperationVariable> Operation::getParameterTypes() const
-{
-	return basyx::specificCollection_t<IOperationVariable>();
-}
-
-std::shared_ptr<IOperationVariable> Operation::getReturnType() const
-{
-	return std::shared_ptr<IOperationVariable>();
-}
-
-basyx::object Operation::getInvocable() const
-{
-	return this->map.getProperty(Path::Invokable);
-}
-
-void Operation::setParameterTypes(const basyx::specificCollection_t<IOperationVariable>& parameterTypes)
-{
-}
-
-void Operation::setReturnTypes(const std::shared_ptr<IOperationVariable>& returnTypes)
-{
-}
-
-void Operation::setInvocable(basyx::object invocable)
-{
-	this->map.insertKey(Path::Invokable, invocable, true);
-}
-
-basyx::object Operation::invoke(basyx::object & parameters) const
-{
-	return basyx::object();
-}
-
-
-
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/submodelelement/operation/OperationVariable.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/submodelelement/operation/OperationVariable.cpp
deleted file mode 100644
index 44183a4..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/submodelelement/operation/OperationVariable.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * ModelType.cpp
- *
- *      Author: wendel
- */
-
-#include <BaSyx/submodel/map/submodelelement/operation/OperationVariable.h>
-
-namespace basyx {
-namespace submodel {
-
-OperationVariable::OperationVariable()
-	: ModelType(IOperationVariable::Path::ModelType)
-  , vab::ElementMap{}
-{}
-
-OperationVariable::OperationVariable(basyx::object object)
-	: vab::ElementMap{object}
-{}
-
-std::shared_ptr<ISubmodelElement> OperationVariable::getValue() const
-{
-	return std::make_shared<SubmodelElement>(this->map.getProperty(IOperationVariable::Path::Value));
-}
-
-std::string OperationVariable::getType() const
-{
-	return this->map.getProperty(Path::Type).GetStringContent();
-}
-
-void OperationVariable::setValue(const SubmodelElement & value)
-{
-	this->map.insertKey(IOperationVariable::Path::Value, value.getMap(), true);
-}
-
-void OperationVariable::setValue(const ISubmodelElement & value)
-{
-  auto map = SubmodelElement(value).getMap();
-  this->map.insertKey(IOperationVariable::Path::Value, map, true);
-}
-
-void OperationVariable::setType(const std::string & string)
-{
-	this->map.insertKey(Path::Type, string, true);
-}
-
-}
-}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/submodelelement/property/Blob.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/submodelelement/property/Blob.cpp
deleted file mode 100644
index 31308ff..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/submodelelement/property/Blob.cpp
+++ /dev/null
@@ -1,34 +0,0 @@
-#include <BaSyx/submodel/map/submodelelement/property/Blob.h>
-
-namespace basyx {
-namespace submodel {
-
-const std::string & Blob::getValue() const
-{
-	return map.getProperty(Blob::Path::Value).Get<std::string&>();
-}
-
-const std::string & Blob::getMimeType() const
-{
-	return map.getProperty(Blob::Path::MIMEType).Get<std::string&>();
-}
-
-void Blob::setValue(const std::string & bytes)
-{
-	this->map.insertKey(Blob::Path::Value, bytes);
-}
-
-void Blob::setValue(const char * c, std::size_t length)
-{
-// TODO: basyx::object for blob types
-//	this->map.insertKey(Blob::Path::Value, basyx::object::make_blob)
-}
-
-void Blob::setMimeType(const std::string & mimeType)
-{
-	this->map.insertKey(IBlob::Path::MIMEType, mimeType, true);
-}
-
-
-}
-};
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/submodelelement/property/File.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/submodelelement/property/File.cpp
deleted file mode 100644
index d6508af..0000000
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map/submodelelement/property/File.cpp
+++ /dev/null
@@ -1,28 +0,0 @@
-#include <BaSyx/submodel/map/submodelelement/property/File.h>
-
-namespace basyx {
-namespace submodel {
-
-const std::string & File::getValue() const
-{
-	return map.getProperty(IFile::Path::Value).Get<std::string&>();
-}
-
-const std::string & File::getMimeType() const
-{
-	return map.getProperty(IFile::Path::MIMEType).Get<std::string&>();
-}
-
-void File::setValue(const std::string & bytes)
-{
-	this->map.insertKey(IFile::Path::Value, bytes);
-}
-
-void File::setMimeType(const std::string & mimeType)
-{
-	this->map.insertKey(IFile::Path::MIMEType, mimeType, true);
-}
-
-
-}
-};
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/SubModel.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/SubModel.cpp
index 56c5f97..10166f9 100644
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/SubModel.cpp
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/SubModel.cpp
@@ -4,12 +4,16 @@
 using namespace basyx::submodel::api;
 using namespace basyx::submodel::map;
 
+constexpr char SubModel::Path::SubmodelElements[];
+constexpr char SubModel::Path::SemanticId[];
+constexpr char SubModel::Path::Kind[];
+
 SubModel::SubModel(const std::string & idShort, const simple::Identifier & identifier, ModelingKind kind)
 	: Identifiable(idShort, identifier)
 {
-	this->map.insertKey("submodelElements", this->elementContainer.getMap());
-	this->map.insertKey("semanticId", semanticId.getMap());
-  this->map.insertKey("kind", ModelingKind_::to_string(kind));
+	this->map.insertKey(Path::SubmodelElements, this->elementContainer.getMap());
+	this->map.insertKey(Path::SemanticId, semanticId.getMap());
+  this->map.insertKey(Path::Kind, ModelingKind_::to_string(kind));
 };
 
 IElementContainer<ISubmodelElement> & SubModel::submodelElements()
@@ -24,7 +28,7 @@
 
 ModelingKind SubModel::getKind() const
 {
-	return ModelingKind_::from_string(this->map.getProperty("kind").GetStringContent());
+	return ModelingKind_::from_string(this->map.getProperty(Path::Kind).GetStringContent());
 }
 
 const IReference & SubModel::getSemanticId() const
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/aas/Asset.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/aas/Asset.cpp
index f66a447..b2f2c72 100644
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/aas/Asset.cpp
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/aas/Asset.cpp
@@ -4,20 +4,24 @@
 using namespace basyx::submodel::api;
 using namespace basyx::submodel::map;
 
+constexpr char Asset::Path::Kind[];
+constexpr char Asset::Path::AssetIdentificationModelRef[];
+constexpr char Asset::Path::BillOfMaterialRef[];
+
 Asset::Asset(const std::string & idShort, const simple::Identifier & identifier, AssetKind kind)
 	: Identifiable(idShort, identifier)
 	, billOfMaterialRef()
 	, assetIdentificationModelRef()
 	, vab::ElementMap()
 {
-	this->map.insertKey("kind", AssetKind_::to_string(kind));
-	this->map.insertKey("assetIdentificationModelRef", assetIdentificationModelRef.getMap());
-	this->map.insertKey("billOfMaterialRef", billOfMaterialRef.getMap());
+	this->map.insertKey(Path::Kind, AssetKind_::to_string(kind));
+	this->map.insertKey(Path::AssetIdentificationModelRef, assetIdentificationModelRef.getMap());
+	this->map.insertKey(Path::BillOfMaterialRef, billOfMaterialRef.getMap());
 };
 
 AssetKind Asset::getKind()
 {
-	return AssetKind_::from_string(this->map.getProperty("kind").Get<std::string&>());
+	return AssetKind_::from_string(this->map.getProperty(Path::Kind).Get<std::string&>());
 };
 
 IReference * const Asset::getAssetIdentificationModel()
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/aas/AssetAdministrationShell.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/aas/AssetAdministrationShell.cpp
index 279a4b4..a518a26 100644
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/aas/AssetAdministrationShell.cpp
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/aas/AssetAdministrationShell.cpp
@@ -4,12 +4,17 @@
 using namespace basyx::submodel::map;
 using namespace basyx::submodel::api;
 
+constexpr char AssetAdministrationShell::Path::Submodels[];
+constexpr char AssetAdministrationShell::Path::Asset[];
+
 AssetAdministrationShell::AssetAdministrationShell(const std::string & idShort, const simple::Identifier & identifier, const Asset & asset)
 	: Identifiable(idShort, identifier)
 	, asset(asset)
+	, submodels(this)
+	, conceptDictionary(this)
 {
-	this->map.insertKey("submodels", submodels.getMap());
-	this->map.insertKey("asset", asset.getMap());
+	this->map.insertKey(Path::Submodels, submodels.getKeyMap());
+	this->map.insertKey(Path::Asset, asset.getMap());
 };
 
 
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/constexpr.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/constexpr.cpp
new file mode 100644
index 0000000..f34285c
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/constexpr.cpp
@@ -0,0 +1,18 @@
+#include <BaSyx/submodel/map_v2/common/ModelType.h>
+#include <BaSyx/submodel/map_v2/common/ElementContainer.h>
+#include <BaSyx/submodel/map_v2/submodelelement/property/Property.h>
+#include <BaSyx/submodel/api_v2/submodelelement/property/XSDAnySimpleType.h>
+
+using namespace basyx::submodel::map;
+
+constexpr char ModelTypePath::Name[];
+constexpr char ModelTypePath::ModelType[];
+
+constexpr char ElementContainerPath::IdShort[];
+
+constexpr char PropertyPath::Value[];
+constexpr char PropertyPath::ValueType[];
+constexpr char PropertyPath::ValueId[];
+
+constexpr char basyx::xsd_types::xsd_type<basyx::submodel::simple::DateTime>::format[];
+constexpr char basyx::xsd_types::xsd_type<basyx::submodel::simple::Date>::format[];
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/constraint/Formula.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/constraint/Formula.cpp
index ca98424..dfcc510 100644
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/constraint/Formula.cpp
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/constraint/Formula.cpp
@@ -5,15 +5,17 @@
 using namespace basyx::submodel;
 using namespace basyx::submodel::map;
 
+constexpr char Formula::Path::Dependencies[];
+
 Formula::Formula()
 {
-	this->map.insertKey("dependencies", basyx::object::make_object_list());
+	this->map.insertKey(Path::Dependencies, basyx::object::make_object_list());
 };
 
 Formula::Formula(const std::vector<simple::Reference> & dependencies)
 	: Formula()
 {
-	auto & objectList = this->map.getProperty("dependencies").Get<basyx::object::object_list_t&>();
+	auto & objectList = this->map.getProperty(Path::Dependencies).Get<basyx::object::object_list_t&>();
 
 	for (const auto & dependency : dependencies)
 	{
@@ -32,7 +34,7 @@
 {
 	std::vector<simple::Reference> dependencies;
 
-	auto & objectList = this->map.getProperty("dependencies").Get<basyx::object::object_list_t&>();
+	auto & objectList = this->map.getProperty(Path::Dependencies).Get<basyx::object::object_list_t&>();
 
 	for (const auto & obj : objectList)
 	{
@@ -48,7 +50,7 @@
 {
 	map::Reference ref{ reference };
 
-	auto & objectList = this->map.getProperty("dependencies").Get<basyx::object::object_list_t&>();
+	auto & objectList = this->map.getProperty(Path::Dependencies).Get<basyx::object::object_list_t&>();
 	objectList.emplace_back(ref.getMap());
 };
 
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/constraint/Qualifier.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/constraint/Qualifier.cpp
index 8a5f9ef..5815a65 100644
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/constraint/Qualifier.cpp
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/constraint/Qualifier.cpp
@@ -5,12 +5,19 @@
 using namespace basyx::submodel::api;
 using namespace basyx::submodel::map;
 
+constexpr char Qualifier::Path::ValueDataType[];
+constexpr char Qualifier::Path::QualifierType[];
+constexpr char Qualifier::Path::ValueType[];
+constexpr char Qualifier::Path::SemanticId[];
+constexpr char Qualifier::Path::ValueId[];
+
+
 Qualifier::Qualifier(const std::string & qualifierType, const std::string & valueType)
 {
-	this->map.insertKey("qualifierType", qualifierType);
-	this->map.insertKey("valueType", valueType);
-	this->map.insertKey("semanticId", this->semanticId.getMap());
-	this->map.insertKey("valueId", this->valueId.getMap());
+	this->map.insertKey(Path::QualifierType, qualifierType);
+	this->map.insertKey(Path::ValueType, valueType);
+	this->map.insertKey(Path::SemanticId, this->semanticId.getMap());
+	this->map.insertKey(Path::ValueId, this->valueId.getMap());
 };
 
 Qualifier::Qualifier(const std::string & qualifierType,
@@ -19,11 +26,11 @@
 	const api::IReference & valueId)
 	: valueId(valueId)
 {
-	this->map.insertKey("valueDataType", valueDataType);
-	this->map.insertKey("qualifierType", qualifierType);
-	this->map.insertKey("valueType", valueType);
-	this->map.insertKey("semanticId", semanticId.getMap());
-	this->map.insertKey("valueId", this->valueId.getMap());
+	this->map.insertKey(Path::ValueDataType, valueDataType);
+	this->map.insertKey(Path::QualifierType, qualifierType);
+	this->map.insertKey(Path::ValueType, valueType);
+	this->map.insertKey(Path::SemanticId, semanticId.getMap());
+	this->map.insertKey(Path::ValueId, this->valueId.getMap());
 };
 
 Qualifier::Qualifier(const api::IQualifier & qualifier)
@@ -38,25 +45,25 @@
 
 const std::string Qualifier::getQualifierType() const
 {
-	return this->map.getProperty("qualifierType").Get<std::string&>();
+	return this->map.getProperty(Path::QualifierType).Get<std::string&>();
 };
 
 const std::string Qualifier::getValueType() const
 {
-	return this->map.getProperty("valueType").Get<std::string&>();
+	return this->map.getProperty(Path::ValueType).Get<std::string&>();
 };
 
 const std::string * const Qualifier::getValueDataType() const
 {
-	if (!this->map.hasProperty("valueDataType"))
+	if (!this->map.hasProperty(Path::ValueDataType))
 		return nullptr;
 
-	return &this->map.getProperty("valueDataType").Get<std::string&>();
+	return &this->map.getProperty(Path::ValueDataType).Get<std::string&>();
 };
 
 void Qualifier::setValueDataType(const std::string & valueDataType)
 {
-	this->map.insertKey("valueDataType", valueDataType);
+	this->map.insertKey(Path::ValueDataType, valueDataType);
 };
 
 const IReference * const Qualifier::getValueId() const
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/dataspecification/DataSpecification.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/dataspecification/DataSpecification.cpp
index ad73e2c..4587e1c 100644
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/dataspecification/DataSpecification.cpp
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/dataspecification/DataSpecification.cpp
@@ -7,6 +7,8 @@
 
 using namespace basyx::submodel::api;
 
+constexpr char DataSpecification::Path::DataSpecificationContent[];
+
 DataSpecification::DataSpecification(const std::string & idShort, const simple::Identifier & identifier, std::unique_ptr<DataSpecificationContent> content)
   : Identifiable(idShort, identifier)
   , vab::ElementMap()
@@ -23,7 +25,7 @@
 {
   this->content = std::move(dataSpecificationContent);
   auto element_map = dynamic_cast<vab::ElementMap*>(this->content.get());
-  this->map.insertKey("dataSpecificationContent", element_map->getMap());
+  this->map.insertKey(Path::DataSpecificationContent, element_map->getMap());
 }
 
 api::IDataSpecificationContent& DataSpecification::getContent()
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/dataspecification/ValueList.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/dataspecification/ValueList.cpp
index 6ac067d..d667054 100644
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/dataspecification/ValueList.cpp
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/dataspecification/ValueList.cpp
@@ -1,9 +1,13 @@
 #include <BaSyx/submodel/map_v2/dataspecification/ValueList.h>
 
+
 namespace basyx {
 namespace submodel {
 namespace map {
 
+constexpr char ValueList::Path::Value[];
+constexpr char ValueList::Path::ValueId[];
+
 ValueList::ValueList()
   : vab::ElementMap(basyx::object::make_object_list())
 {}
@@ -15,8 +19,8 @@
 void ValueList::addValueReferencePair(const simple::ValueReferencePair & valueRefPair)
 {
   object obj = object::make_map();
-  obj.insertKey("value", valueRefPair.getValue());
-  obj.insertKey("valueId", map::Reference(valueRefPair.getValueId()).getMap());
+  obj.insertKey(Path::Value, valueRefPair.getValue());
+  obj.insertKey(Path::ValueId, map::Reference(valueRefPair.getValueId()).getMap());
   this->map.insert(obj);
 }
 
@@ -25,8 +29,8 @@
   std::vector<simple::ValueReferencePair> list;
   for (auto & pair_obj : this->map.Get<object::object_list_t&>())
   {
-    std::string value = pair_obj.getProperty("value").GetStringContent();
-    auto reference = simple::Reference(map::Reference(pair_obj.getProperty("valueId")));
+    std::string value = pair_obj.getProperty(Path::Value).GetStringContent();
+    auto reference = simple::Reference(map::Reference(pair_obj.getProperty(Path::ValueId)));
     simple::ValueReferencePair pair(value, reference);
     list.push_back(pair);
   }
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/parts/ConceptDictionary.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/parts/ConceptDictionary.cpp
index 2cb4a84..9dd734f 100644
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/parts/ConceptDictionary.cpp
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/parts/ConceptDictionary.cpp
@@ -4,13 +4,16 @@
 namespace basyx {
 namespace submodel {
 namespace map {
+
 using namespace basyx::submodel::api;
 
+constexpr char ConceptDictionary::Path::ConceptDescriptions[];
+
 ConceptDictionary::ConceptDictionary(const std::string & idShort)
   : vab::ElementMap{}
   , Referable(idShort)
 {
-  this->map.insertKey("ConceptDescriptions", this->concept_descriptions.getMap());
+  this->map.insertKey(Path::ConceptDescriptions, this->concept_descriptions.getMap());
 }
 
 const api::IElementContainer<api::IConceptDescription> & ConceptDictionary::getConceptDescriptions() const
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/parts/View.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/parts/View.cpp
index b973acc..431b9d9 100644
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/parts/View.cpp
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/parts/View.cpp
@@ -3,12 +3,15 @@
 using namespace basyx::submodel;
 using namespace basyx::submodel::map;
 
-View::View(const std::string &idShort, const Referable *parent)
+constexpr char View::Path::ContainedElements[];
+constexpr char View::Path::SemanticId[];
+
+View::View(const std::string &idShort, Referable *parent)
   : vab::ElementMap{}
   , Referable(idShort, parent)
 {
-  this->map.insertKey("ContainedElements", this->contained_elements.getMap());
-  this->map.insertKey("SemanticId", this->semanticId.getMap());
+  this->map.insertKey(Path::ContainedElements, this->contained_elements.getMap());
+  this->map.insertKey(Path::SemanticId, this->semanticId.getMap());
 }
 
 const api::IElementContainer<api::IReferable> & View::getContainedElements() const
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/qualifier/AdministrativeInformation.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/qualifier/AdministrativeInformation.cpp
new file mode 100644
index 0000000..5a35320
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/qualifier/AdministrativeInformation.cpp
@@ -0,0 +1,62 @@
+#include <BaSyx/submodel/map_v2/qualifier/AdministrativeInformation.h>
+
+
+namespace basyx {
+namespace submodel {
+namespace map {
+
+using namespace basyx::submodel::api;
+
+constexpr char AdministrativeInformation::Path::Version[];
+constexpr char AdministrativeInformation::Path::Revision[];
+
+AdministrativeInformation::AdministrativeInformation()
+{}
+
+AdministrativeInformation::AdministrativeInformation(const std::string &version, const std::string &revision)
+{
+  this->map.insertKey(Path::Version, version);
+  this->map.insertKey(Path::Revision, revision);
+}
+
+void AdministrativeInformation::setVersion(const std::string &version)
+{
+  this->map.insertKey(Path::Version, version);
+}
+
+void AdministrativeInformation::setRevision(const std::string &revision)
+{
+  this->map.insertKey(Path::Revision, revision);
+}
+
+bool AdministrativeInformation::hasVersion() const
+{
+  return not this->map.getProperty(Path::Version).IsNull();
+}
+
+bool AdministrativeInformation::hasRevision() const
+{
+  return not this->map.getProperty(Path::Revision).IsNull();
+}
+
+const std::string * const AdministrativeInformation::getVersion() const
+{
+  auto version = this->map.getProperty(Path::Version);
+  if (version.IsNull())
+    return nullptr;
+
+  return &version.Get<std::string&>();
+}
+
+const std::string * const AdministrativeInformation::getRevision() const
+{
+  auto revision = this->map.getProperty(Path::Revision);
+  if (revision.IsNull())
+    return nullptr;
+
+  return &revision.Get<std::string&>();
+}
+
+}
+}
+}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/qualifier/HasDataSpecification.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/qualifier/HasDataSpecification.cpp
index 8dc93bb..1f52305 100644
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/qualifier/HasDataSpecification.cpp
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/qualifier/HasDataSpecification.cpp
@@ -7,11 +7,13 @@
 using namespace basyx::submodel::api;
 using namespace basyx::submodel::map;
 
+constexpr char HasDataSpecification::Path::DataSpecification[];
+
 HasDataSpecification::HasDataSpecification()
 	: vab::ElementMap()
 	, dataSpecification()
 {
-	this->map.insertKey("dataSpecification", basyx::object::make_object_ref(&dataSpecification));
+	this->map.insertKey(Path::DataSpecification, this->dataSpecification);
 }
 
 void HasDataSpecification::addDataSpecification(const simple::Reference & reference)
@@ -34,4 +36,4 @@
 	};
 
 	return dataSpecs;
-}
\ No newline at end of file
+}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/qualifier/Identifiable.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/qualifier/Identifiable.cpp
index 6d7cab8..882f8ce 100644
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/qualifier/Identifiable.cpp
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/qualifier/Identifiable.cpp
@@ -4,44 +4,47 @@
 using namespace basyx::submodel::map;
 using namespace basyx::submodel::api;
 
-struct IdentifierPath {
-	static constexpr char IdType[] = "idType";
-	static constexpr char Id[] = "id";
-};
-
-constexpr char IdentifierPath::IdType[];
-constexpr char IdentifierPath::Id[];
+constexpr char Identifiable::Path::IdType[];
+constexpr char Identifiable::Path::Id[];
+constexpr char Identifiable::Path::AdministrativeInformation[];
+constexpr char Identifiable::Path::Identifier[];
 
 Identifiable::Identifiable(const std::string & idShort, const simple::Identifier & identifier)
 	: Referable(idShort)
 	, vab::ElementMap()
 {
 	auto identifierMap = basyx::object::make_map();
-	identifierMap.insertKey(IdentifierPath::Id, identifier.getId());
-	identifierMap.insertKey(IdentifierPath::IdType, IdentifierType_::to_string(identifier.getIdType()));
-	this->map.insertKey("identifier", identifierMap);
+	identifierMap.insertKey(Path::Id, identifier.getId());
+	identifierMap.insertKey(Path::IdType, IdentifierType_::to_string(identifier.getIdType()));
+	this->map.insertKey(Path::Identifier, identifierMap);
 }
 
 bool Identifiable::hasAdministrativeInformation() const noexcept
-{ 
-	return this->administrativeInformation.exists(); 
+{
+  return not this->map.getProperty(Path::AdministrativeInformation).IsNull();
 };
 
 simple::Identifier Identifiable::getIdentification() const
 {
-	auto identifierMap = this->map.getProperty("identifier");
+	auto identifierMap = this->map.getProperty(Path::Identifier);
 	return simple::Identifier{
-		IdentifierType_::from_string(identifierMap.getProperty(IdentifierPath::IdType).Get<std::string&>()),
-		identifierMap.getProperty(IdentifierPath::Id).Get<std::string&>()
+		IdentifierType_::from_string(identifierMap.getProperty(Path::IdType).Get<std::string&>()),
+		identifierMap.getProperty(Path::Id).Get<std::string&>()
 	};
 }
 
-const simple::AdministrativeInformation & Identifiable::getAdministrativeInformation() const
+const api::IAdministrativeInformation & Identifiable::getAdministrativeInformation() const
 {
 	return this->administrativeInformation;
 }
 
-simple::AdministrativeInformation & Identifiable::getAdministrativeInformation()
+api::IAdministrativeInformation & Identifiable::getAdministrativeInformation()
 {
 	return this->administrativeInformation;
 }
+
+void Identifiable::setAdministrativeInformation(const AdministrativeInformation &administrativeInformation)
+{
+  this->administrativeInformation = administrativeInformation;
+  this->map.insertKey(Path::AdministrativeInformation, this->administrativeInformation.getMap());
+}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/qualifier/Qualifiable.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/qualifier/Qualifiable.cpp
index 1aedb59..7c1c07e 100644
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/qualifier/Qualifiable.cpp
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/qualifier/Qualifiable.cpp
@@ -7,16 +7,18 @@
 using namespace basyx::submodel::api;
 using namespace basyx::submodel::map;
 
+constexpr char Qualifiable::Path::Qualifier[];
+
 Qualifiable::Qualifiable(const std::vector<simple::Formula> & formulas, const std::vector<simple::Qualifier> & qualifiers)
 {
-	this->map.insertKey("qualifier", basyx::object::make_object_list());
+	this->map.insertKey(Path::Qualifier, basyx::object::make_object_list());
 };
 
 void Qualifiable::addFormula(const api::IFormula & formula)
 {
 	map::Formula f{ formula };
 
-	auto & objectList = this->map.getProperty("qualifier").Get<basyx::object::object_list_t&>();
+	auto & objectList = this->map.getProperty(Path::Qualifier).Get<basyx::object::object_list_t&>();
 
 	objectList.emplace_back(f.getMap());
 }
@@ -25,7 +27,7 @@
 {
 	map::Qualifier q{ qualifier };
 
-	auto & objectList = this->map.getProperty("qualifier").Get<basyx::object::object_list_t&>();
+	auto & objectList = this->map.getProperty(Path::Qualifier).Get<basyx::object::object_list_t&>();
 
 	objectList.emplace_back(q.getMap());
 }
@@ -34,7 +36,7 @@
 {
 	std::vector<simple::Formula> formulas;
 
-	auto & objectList = this->map.getProperty("qualifier").Get<basyx::object::object_list_t&>();
+	auto & objectList = this->map.getProperty(Path::Qualifier).Get<basyx::object::object_list_t&>();
 	for (auto & object : objectList)
 	{
 		if(ModelType<ModelTypes::Constraint>(object).GetModelType() == ModelTypes::Formula)
@@ -51,7 +53,7 @@
 {
 	std::vector<simple::Qualifier> qualifiers;
 
-	auto & objectList = this->map.getProperty("qualifier").Get<basyx::object::object_list_t&>();
+	auto & objectList = this->map.getProperty(Path::Qualifier).Get<basyx::object::object_list_t&>();
 	for (auto & object : objectList)
 	{
 		if (ModelType<ModelTypes::Constraint>(object).GetModelType() == ModelTypes::Qualifier)
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/qualifier/Referable.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/qualifier/Referable.cpp
index 83de297..a85a21a 100644
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/qualifier/Referable.cpp
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/qualifier/Referable.cpp
@@ -1,6 +1,7 @@
 #include <BaSyx/submodel/map_v2/qualifier/Referable.h>
-#include <BaSyx/submodel/map_v2/reference/Reference.h>
+#include <BaSyx/submodel/simple/reference/Reference.h>
 
+using namespace basyx::submodel;
 using namespace basyx::submodel::map;
 using namespace basyx::submodel::api;
 
@@ -9,7 +10,7 @@
 constexpr char Referable::Path::Description[];
 constexpr char Referable::Path::Parent[];
 
-Referable::Referable(const std::string & idShort, const Referable * parent)
+Referable::Referable(const std::string & idShort, Referable * parent)
 	: parent(parent)
 	, vab::ElementMap(basyx::object::make_map())
 {
@@ -51,7 +52,12 @@
 	this->map.insertKey(Path::Category, category);
 }
 
-const IReferable * const Referable::getParent() const
+void Referable::setParent(IReferable * parent)
+{
+	this->parent = parent;
+};
+
+IReferable * Referable::getParent() const
 {
 	return this->parent;
 };
@@ -69,4 +75,23 @@
 bool Referable::hasCategory() const noexcept 
 {
 	return this->map.hasProperty(Path::Category);
-};
\ No newline at end of file
+};
+
+simple::Reference Referable::getReference() const
+{
+	auto key = this->getKey();
+
+	if (this->getParent() == nullptr)
+		return simple::Reference(key);
+
+	auto reference = this->getParent()->getReference();
+
+	reference.addKey(key);
+
+	return reference;
+}
+
+simple::Key Referable::getKey(bool local) const
+{
+	return simple::Key(this->getKeyElementType(), local, this->getKeyType(), this->getIdShort());
+}
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/reference/Reference.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/reference/Reference.cpp
index 818e94a..1a7de69 100644
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/reference/Reference.cpp
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/reference/Reference.cpp
@@ -8,23 +8,16 @@
 using namespace basyx::submodel;
 using namespace basyx::submodel::map;
 
-struct KeyPath
-{
-	static constexpr char IdType[] = "idType";
-	static constexpr char Type[] = "type";
-	static constexpr char Value[] = "value";
-	static constexpr char Local[] = "local";
-};
-
-constexpr char KeyPath::IdType[];
-constexpr char KeyPath::Type[];
-constexpr char KeyPath::Value[];
-constexpr char KeyPath::Local[];
+constexpr char Reference::Path::IdType[];
+constexpr char Reference::Path::Type[];
+constexpr char Reference::Path::Value[];
+constexpr char Reference::Path::Local[];
+constexpr char Reference::Path::Keys[];
 
 Reference::Reference() 
 	: vab::ElementMap{}
 {
-	this->map.insertKey("keys", basyx::object::make_object_list());
+	this->map.insertKey(Path::Keys, basyx::object::make_object_list());
 }
 
 Reference::Reference(const simple::Key & key)
@@ -46,29 +39,29 @@
 
 
 Reference::Reference(basyx::object &object)
-  : Reference(keyMapList_to_keyList(object.getProperty("keys").Get<object::object_list_t&>()))
+  : Reference(keyMapList_to_keyList(object.getProperty(Path::Keys).Get<object::object_list_t&>()))
 {}
 
 
 std::vector<simple::Key> Reference::getKeys() const
 {
-	return this->keyMapList_to_keyList(this->map.getProperty("keys").Get<basyx::object::object_list_t&>());
+	return this->keyMapList_to_keyList(this->map.getProperty(Path::Keys).Get<basyx::object::object_list_t&>());
 };
 
 
 void Reference::addKey(const simple::Key & key)
 {
 	basyx::object keyMap = basyx::object::make_map();
-	keyMap.insertKey(KeyPath::IdType, KeyType_::to_string(key.getIdType()));
-	keyMap.insertKey(KeyPath::Type, KeyElements_::to_string(key.getType()));
-	keyMap.insertKey(KeyPath::Value, key.getValue());
-	keyMap.insertKey(KeyPath::Local, key.isLocal());
-	this->map.getProperty("keys").insert(keyMap);
+	keyMap.insertKey(Path::IdType, KeyType_::to_string(key.getIdType()));
+	keyMap.insertKey(Path::Type, KeyElements_::to_string(key.getType()));
+	keyMap.insertKey(Path::Value, key.getValue());
+	keyMap.insertKey(Path::Local, key.isLocal());
+	this->map.getProperty(Path::Keys).insert(keyMap);
 }
 
 Reference & Reference::operator=(const api::IReference & other)
 {
-	this->map.insertKey("keys", basyx::object::make_object_list());
+	this->map.insertKey(Path::Keys, basyx::object::make_object_list());
 
 	for (const auto & key : other.getKeys())
 		this->addKey(key);
@@ -79,17 +72,17 @@
 
 bool Reference::empty() const
 {
-	return this->map.getProperty("keys").empty();
+	return this->map.getProperty(Path::Keys).empty();
 }
 
 simple::Key Reference::keyMap_to_key(basyx::object &keyMap)
 {
   return simple::Key
   (
-    KeyElements_::from_string(keyMap.getProperty(KeyPath::Type).Get<std::string&>()),
-    keyMap.getProperty(KeyPath::Local).Get<bool>(),
-    KeyType_::from_string(keyMap.getProperty(KeyPath::IdType).Get<std::string&>()),
-    keyMap.getProperty(KeyPath::Value).Get<std::string&>()
+    KeyElements_::from_string(keyMap.getProperty(Path::Type).Get<std::string&>()),
+    keyMap.getProperty(Path::Local).Get<bool>(),
+    KeyType_::from_string(keyMap.getProperty(Path::IdType).Get<std::string&>()),
+    keyMap.getProperty(Path::Value).Get<std::string&>()
   );
 }
 
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/submodelelement/SubmodelElement.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/submodelelement/SubmodelElement.cpp
index 60193e7..11441de 100644
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/submodelelement/SubmodelElement.cpp
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/submodelelement/SubmodelElement.cpp
@@ -4,14 +4,17 @@
 using namespace basyx::submodel::api;
 using namespace basyx::submodel::map;
 
+constexpr char SubmodelElement::Path::Kind[];
+constexpr char SubmodelElement::Path::SemanticId[];
+
 SubmodelElement::SubmodelElement(const std::string & idShort, ModelingKind kind)
 	: Referable(idShort, nullptr)
 	, HasDataSpecification()
 	, semanticId()
 	, vab::ElementMap{}
 {
-	this->map.insertKey("kind", ModelingKind_::to_string(kind));
-	this->map.insertKey("semanticId", semanticId.getMap());
+	this->map.insertKey(Path::Kind, ModelingKind_::to_string(kind));
+	this->map.insertKey(Path::SemanticId, semanticId.getMap());
 }
 
 const api::IReference & SubmodelElement::getSemanticId() const
@@ -26,5 +29,5 @@
 
 ModelingKind SubmodelElement::getKind() const
 {
-	return ModelingKind_::from_string(this->map.getProperty("kind").GetStringContent());
+	return ModelingKind_::from_string(this->map.getProperty(Path::Kind).GetStringContent());
 }
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/submodelelement/SubmodelElementFactory.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/submodelelement/SubmodelElementFactory.cpp
index fb53647..5585bbf 100644
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/submodelelement/SubmodelElementFactory.cpp
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/submodelelement/SubmodelElementFactory.cpp
@@ -11,10 +11,12 @@
 using namespace basyx::submodel::api;
 using namespace basyx::submodel::map;
 
+constexpr char SubmodelElementFactory::Path::Value[];
+
 std::unique_ptr<ISubmodelElement> SubmodelElementFactory::CreateProperty(const vab::ElementMap & elementMap)
 {
 	auto object = elementMap.getMap();
-	auto value = object.getProperty("value");
+	auto value = object.getProperty(Path::Value);
 	auto type = value.GetValueType();
 
 	switch (type)
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/submodelelement/operation/Operation.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/submodelelement/operation/Operation.cpp
index f4a1a51..105fe60 100644
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/submodelelement/operation/Operation.cpp
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/submodelelement/operation/Operation.cpp
@@ -3,14 +3,20 @@
 using namespace basyx::submodel::map;
 using namespace basyx::submodel::api;
 
+constexpr char Operation::Path::Invokable[];
+constexpr char Operation::Path::InputVariable[];
+constexpr char Operation::Path::OutputVariable[];
+constexpr char Operation::Path::InoutputVariable[];
+
 Operation::Operation(const std::string & idShort, basyx::object invokable)
 	: SubmodelElement(idShort)
 	, invokable(basyx::object::make_null())
 {
 	this->invokable = invokable;
-	this->map.insertKey("inputVariable", inputVariables.getMap());
-	this->map.insertKey("outputVariable", outputVariables.getMap());
-	this->map.insertKey("inoutputVariable", inOutVariables.getMap());
+	this->map.insertKey(Path::Invokable, this->invokable);
+	this->map.insertKey(Path::InputVariable, inputVariables.getMap());
+	this->map.insertKey(Path::OutputVariable, outputVariables.getMap());
+	this->map.insertKey(Path::InoutputVariable, inOutVariables.getMap());
 };
 
 IElementContainer<ISubmodelElement> & Operation::getInputVariables()
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/submodelelement/property/MultiLanguageProperty.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/submodelelement/property/MultiLanguageProperty.cpp
index d9d2fec..b2ee7f8 100644
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/submodelelement/property/MultiLanguageProperty.cpp
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/submodelelement/property/MultiLanguageProperty.cpp
@@ -4,12 +4,16 @@
 using namespace basyx::submodel::api;
 using namespace basyx::submodel::map;
 
+constexpr char MultiLanguageProperty::Path::Value[];
+constexpr char MultiLanguageProperty::Path::ValueId[];
+constexpr char MultiLanguageProperty::Path::Kind[];
+
 MultiLanguageProperty::MultiLanguageProperty(const std::string & idShort, ModelingKind kind)
 	: SubmodelElement(idShort, kind)
 {
-	this->map.insertKey("value", value.getMap());
-	this->map.insertKey("valueId", valueId.getMap());
-  this->map.insertKey("kind", ModelingKind_::to_string(kind));
+	this->map.insertKey(Path::Value, value.getMap());
+	this->map.insertKey(Path::ValueId, valueId.getMap());
+  this->map.insertKey(Path::Kind, ModelingKind_::to_string(kind));
 };
 
 api::ILangStringSet & MultiLanguageProperty::getValue()
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/submodelelement/property/ReferenceElement.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/submodelelement/property/ReferenceElement.cpp
index e4b0d09..d948553 100644
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/submodelelement/property/ReferenceElement.cpp
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/submodelelement/property/ReferenceElement.cpp
@@ -4,11 +4,14 @@
 using namespace basyx::submodel::api;
 using namespace basyx::submodel::map;
 
+constexpr char ReferenceElement::Path::Value[];
+constexpr char ReferenceElement::Path::Kind[];
+
 ReferenceElement::ReferenceElement(const std::string & idShort, ModelingKind kind)
 	: SubmodelElement(idShort, kind)
 {
-	this->map.insertKey("value", value.getMap());
-  this->map.insertKey("kind", ModelingKind_::to_string(kind));
+	this->map.insertKey(Path::Value, value.getMap());
+  this->map.insertKey(Path::Kind, ModelingKind_::to_string(kind));
 };
 
 const api::IReference * const ReferenceElement::getValue() const
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/SubModel.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/SubModel.cpp
index fb0adef..9841050 100644
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/SubModel.cpp
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/SubModel.cpp
@@ -50,11 +50,16 @@
 	return this->identifiable.getDescription();
 }
 
-const IReferable * const SubModel::getParent() const
+IReferable * SubModel::getParent() const
 {
 	return this->identifiable.getParent();
 }
 
+void SubModel::setParent(IReferable * parent)
+{
+	return this->identifiable.setParent(parent);
+};
+
 const AdministrativeInformation & SubModel::getAdministrativeInformation() const
 {
 	return this->identifiable.getAdministrativeInformation();
@@ -115,3 +120,12 @@
 	return this->qualifiable.getQualifiers();
 };
 
+simple::Reference SubModel::getReference() const
+{
+	return this->identifiable.getReference();
+};
+
+simple::Key SubModel::getKey(bool local) const
+{
+	return this->identifiable.getKey();
+};
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/aas/Asset.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/aas/Asset.cpp
index ab139d4..6cddc4b 100644
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/aas/Asset.cpp
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/aas/Asset.cpp
@@ -82,11 +82,16 @@
 	return this->identifiable.getDescription();
 }
 
-const api::IReferable * const Asset::getParent() const
+api::IReferable * Asset::getParent() const
 {
 	return this->identifiable.getParent();
 }
 
+void Asset::setParent(IReferable * parent)
+{
+	this->identifiable.setParent(parent);
+}
+
 const AdministrativeInformation & Asset::getAdministrativeInformation() const
 {
 	return this->identifiable.getAdministrativeInformation();
@@ -102,6 +107,17 @@
 	return this->identifiable.getIdentification();
 }
 
+simple::Reference Asset::getReference() const
+{
+	return this->identifiable.getReference();
+};
+
+simple::Key Asset::getKey(bool local) const
+{
+	return this->identifiable.getKey();
+};
+
+
 }
 }
 }
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/aas/AssetAdministrationShell.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/aas/AssetAdministrationShell.cpp
index 687800e..ec9bed5 100644
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/aas/AssetAdministrationShell.cpp
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/aas/AssetAdministrationShell.cpp
@@ -1,8 +1,10 @@
 #include <BaSyx/submodel/simple/aas/AssetAdministrationShell.h>
 #include <BaSyx/submodel/simple/reference/Reference.h>
+#include <BaSyx/submodel/enumerations/ModelTypes.h>
 
-using namespace basyx::submodel::simple;
+using namespace basyx::submodel;
 using namespace basyx::submodel::api;
+using namespace basyx::submodel::simple;
 
 AssetAdministrationShell::AssetAdministrationShell(const std::string & idShort, const Identifier & identifier, const Asset & asset)
 	: identifiable(idShort, identifier)
@@ -11,7 +13,6 @@
 	
 };
 
-
 ElementContainer<IConceptDescription> & AssetAdministrationShell::getConceptDictionary()
 {
 	return this->conceptDictionary;
@@ -63,17 +64,23 @@
 	return this->identifiable.getDescription();
 }
 
-const IReferable * const AssetAdministrationShell::getParent() const
+IReferable * AssetAdministrationShell::getParent() const
 {
 	return this->identifiable.getParent();
 }
 
-const AdministrativeInformation & AssetAdministrationShell::getAdministrativeInformation() const
+void AssetAdministrationShell::setParent(IReferable * parent)
+{
+	this->identifiable.setParent(parent);
+}
+
+
+const api::IAdministrativeInformation & AssetAdministrationShell::getAdministrativeInformation() const
 {
 	return this->identifiable.getAdministrativeInformation();
 }
 
-AdministrativeInformation & AssetAdministrationShell::getAdministrativeInformation()
+api::IAdministrativeInformation & AssetAdministrationShell::getAdministrativeInformation()
 {
 	return this->identifiable.getAdministrativeInformation();
 }
@@ -98,3 +105,19 @@
 {
 	return this->dataSpecification.getDataSpecificationReference();
 }
+
+simple::Reference AssetAdministrationShell::getReference() const
+{
+	return this->identifiable.getReference();
+};
+
+
+ModelTypes AssetAdministrationShell::GetModelType() const
+{
+	return ModelTypes::AssetAdministrationShell;
+}
+
+simple::Key AssetAdministrationShell::getKey(bool local) const
+{
+	return this->identifiable.getKey();
+};
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/common/xsd_types/AnyURI.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/common/xsd_types/AnyURI.cpp
new file mode 100644
index 0000000..3c991c1
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/common/xsd_types/AnyURI.cpp
@@ -0,0 +1,24 @@
+#include <BaSyx/submodel/simple/common/xsd_types/AnyURI.h>
+
+namespace basyx {
+namespace submodel {
+namespace simple {
+
+AnyURI::AnyURI(const std::string & uri)
+  : uri{uri}
+{}
+
+const std::string &AnyURI::getUri() const
+{
+  return this->uri;
+}
+
+void AnyURI::setURI(const std::string &uri)
+{
+  this->uri = uri;
+}
+
+
+}
+}
+}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/common/xsd_types/Date.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/common/xsd_types/Date.cpp
new file mode 100644
index 0000000..e77a195
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/common/xsd_types/Date.cpp
@@ -0,0 +1,24 @@
+#include <BaSyx/submodel/simple/common/xsd_types/Date.h>
+
+
+namespace basyx {
+namespace submodel {
+namespace simple {
+
+Date::Date(const tm & date)
+    : date{date}
+{}
+
+const tm &Date::getDate() const
+{
+  return this->date;
+}
+
+void Date::setDate(const tm & date)
+{
+  this->date = date;
+}
+
+}
+}
+}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/common/xsd_types/DateTime.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/common/xsd_types/DateTime.cpp
new file mode 100644
index 0000000..291c6aa
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/common/xsd_types/DateTime.cpp
@@ -0,0 +1,24 @@
+#include <BaSyx/submodel/simple/common/xsd_types/DateTime.h>
+#include <chrono>
+
+namespace basyx {
+namespace submodel {
+namespace simple {
+
+DateTime::DateTime(const tm & time)
+  : time{time}
+{}
+
+const tm &DateTime::getTime() const
+{
+  return this->time;
+}
+
+void DateTime::setTime(const tm & time)
+{
+  this->time = time;
+}
+
+}
+}
+}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/common/xsd_types/DayTimeDuration.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/common/xsd_types/DayTimeDuration.cpp
new file mode 100644
index 0000000..a62ef86
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/common/xsd_types/DayTimeDuration.cpp
@@ -0,0 +1,25 @@
+#include <BaSyx/submodel/simple/common/xsd_types/DayTimeDuration.h>
+#include <chrono>
+
+
+namespace basyx {
+namespace submodel {
+namespace simple {
+
+DayTimeDuration::DayTimeDuration(const std::chrono::duration<long> & duration)
+  : duration_in_sec{duration}
+{}
+
+const std::chrono::duration<long> &DayTimeDuration::getDuration() const
+{
+  return this->duration_in_sec;
+}
+
+void DayTimeDuration::setDuration(const std::chrono::duration<long> & duration)
+{
+  this->duration_in_sec = duration;
+}
+
+}
+}
+}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/common/xsd_types/GDay.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/common/xsd_types/GDay.cpp
new file mode 100644
index 0000000..1348725
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/common/xsd_types/GDay.cpp
@@ -0,0 +1,39 @@
+#include <BaSyx/submodel/simple/common/xsd_types/GDay.h>
+
+
+namespace basyx {
+namespace submodel {
+namespace simple {
+
+GDay::GDay(uint8_t day, const Timezone & timezone)
+  : timezone{timezone}
+{
+  this->setDay(day);
+}
+
+uint8_t GDay::getDay() const
+{
+  return this->day;
+}
+
+void GDay::setDay(uint8_t day)
+{
+  day %= 31;
+  if (day == 0)
+    day = 31;
+  this->day = day;
+}
+
+const Timezone &GDay::getTimezone() const
+{
+  return this->timezone;
+}
+
+void GDay::setTimezone(const Timezone &timezone)
+{
+  this->timezone = timezone;
+}
+
+}
+}
+}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/common/xsd_types/GMonth.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/common/xsd_types/GMonth.cpp
new file mode 100644
index 0000000..27fc0d3
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/common/xsd_types/GMonth.cpp
@@ -0,0 +1,40 @@
+#include <BaSyx/submodel/simple/common/xsd_types/GMonth.h>
+
+
+namespace basyx {
+namespace submodel {
+namespace simple {
+
+GMonth::GMonth(uint8_t month, const Timezone &timezone)
+  : timezone{timezone}
+{
+  this->setMonth(month);
+}
+
+
+uint8_t GMonth::getMonth() const
+{
+  return this->month;
+}
+
+void GMonth::setMonth(uint8_t month)
+{
+  month %= 12;
+  if (month == 0)
+    month = 12;
+  this->month = month;
+}
+
+const Timezone &GMonth::getTimezone() const
+{
+  return this->timezone;
+}
+
+void GMonth::setTimezone(const Timezone &timezone)
+{
+  this->timezone = timezone;
+}
+
+}
+}
+}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/common/xsd_types/GMonthDay.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/common/xsd_types/GMonthDay.cpp
new file mode 100644
index 0000000..30560da
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/common/xsd_types/GMonthDay.cpp
@@ -0,0 +1,54 @@
+#include <BaSyx/submodel/simple/common/xsd_types/GMonthDay.h>
+
+namespace basyx {
+namespace submodel {
+namespace simple {
+
+GMonthDay::GMonthDay(uint8_t month, uint8_t day, const Timezone & timezone)
+  : timezone{timezone}
+{
+  this->setMonth(month);
+  this->setDay(day);
+}
+
+uint8_t GMonthDay::getMonth() const
+{
+  return this->month;
+}
+
+void GMonthDay::setMonth(uint8_t month)
+{
+  month %= 12;
+  if (month == 0)
+    month = 12;
+  this->month = month;
+  // re-check day
+  this->setDay(this->day);
+}
+
+uint8_t GMonthDay::getDay() const
+{
+  return this->day;
+}
+
+void GMonthDay::setDay(uint8_t day)
+{
+  if (day > month_days[this->month - 1])
+    this->day = month_days[this->month - 1];
+  else
+    this->day = day;
+}
+
+const Timezone & GMonthDay::getTimezone() const
+{
+  return this->timezone;
+}
+
+void GMonthDay::setTimezone(const Timezone & timezone)
+{
+  this->timezone = timezone;
+}
+
+}
+}
+}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/common/xsd_types/GYear.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/common/xsd_types/GYear.cpp
new file mode 100644
index 0000000..905dc37
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/common/xsd_types/GYear.cpp
@@ -0,0 +1,35 @@
+#include <BaSyx/submodel/simple/common/xsd_types/GYear.h>
+
+
+namespace basyx {
+namespace submodel {
+namespace simple {
+
+GYear::GYear(int year, const Timezone & timezone)
+  : year{year}
+  , timezone{timezone}
+{}
+
+int GYear::getYear() const
+{
+  return year;
+}
+
+void GYear::setYear(int year)
+{
+  this->year = this->year;
+}
+
+const Timezone & GYear::getTimezone() const
+{
+  return this->timezone;
+}
+
+void GYear::setTimezone(const Timezone & timezone)
+{
+  this->timezone = timezone;
+}
+
+}
+}
+}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/common/xsd_types/GYearMonth.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/common/xsd_types/GYearMonth.cpp
new file mode 100644
index 0000000..3085f4d
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/common/xsd_types/GYearMonth.cpp
@@ -0,0 +1,51 @@
+#include <BaSyx/submodel/simple/common/xsd_types/GYearMonth.h>
+
+
+namespace basyx {
+namespace submodel {
+namespace simple {
+
+GYearMonth::GYearMonth(int year, uint8_t month, const Timezone & timezone)
+  : year{year}
+  , timezone{timezone}
+{
+  this->setMonth(month);
+}
+
+int GYearMonth::getYear() const
+{
+  return year;
+}
+
+void GYearMonth::setYear(int year)
+{
+  this->year = year;
+}
+
+uint8_t GYearMonth::getMonth() const
+{
+  return month;
+}
+
+void GYearMonth::setMonth(uint8_t month)
+{
+  //fit month in 1-12
+  month %= 13;
+  if (!month)
+    month = 12;
+  this->month = month;
+}
+
+const Timezone &GYearMonth::getTimezone() const
+{
+  return timezone;
+}
+
+void GYearMonth::setTimezone(const Timezone &timezone)
+{
+  this->timezone = timezone;
+}
+
+}
+}
+}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/common/xsd_types/Time.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/common/xsd_types/Time.cpp
new file mode 100644
index 0000000..1ea8b94
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/common/xsd_types/Time.cpp
@@ -0,0 +1,66 @@
+#include <BaSyx/submodel/simple/common/xsd_types/Time.h>
+
+
+namespace basyx {
+namespace submodel {
+namespace simple {
+
+Time::Time(uint8_t hours, uint8_t minutes, float seconds, const Timezone & timezone)
+  : timezone{timezone}
+{
+  this->setHours(hours);
+  this->setMinutes(minutes);
+  this->setSeconds(seconds);
+}
+
+uint8_t Time::getHours() const
+{
+  return this->hours;
+}
+
+void Time::setHours(uint8_t hours)
+{
+  this->hours = hours % 24;
+}
+
+uint8_t Time::getMinutes() const
+{
+  return this->minutes;
+}
+
+void Time::setMinutes(uint8_t minutes)
+{
+  this->minutes = minutes % 60;
+}
+
+float Time::getSeconds() const
+{
+  return this->seconds;
+}
+
+void Time::setSeconds(float seconds)
+{
+  if (seconds < 61)
+  {
+    this->seconds = seconds;
+    return;
+  }
+  int full_seconds = int(seconds);
+  seconds -= full_seconds;
+  full_seconds %= 60;
+  this->seconds += full_seconds;
+}
+
+const Timezone & Time::getTimezone() const
+{
+  return this->timezone;
+}
+
+void Time::setTimezone(const Timezone & timezone)
+{
+  this->timezone = timezone;
+}
+
+}
+}
+}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/common/xsd_types/Timezone.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/common/xsd_types/Timezone.cpp
new file mode 100644
index 0000000..944711c
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/common/xsd_types/Timezone.cpp
@@ -0,0 +1,44 @@
+#include <BaSyx/submodel/simple/common/xsd_types/Timezone.h>
+
+
+namespace basyx {
+namespace submodel {
+namespace simple {
+
+Timezone::Timezone()
+  : timezone{"Z"}
+{}
+
+Timezone::Timezone(const std::string & timezone)
+  : timezone{timezone}
+{}
+
+Timezone::Timezone(const char * timezone)
+  : timezone{timezone}
+{
+
+}
+
+const std::string &Timezone::getTimezone() const
+{
+  return this->timezone;
+}
+
+void Timezone::setTimezone(const std::string &timezone)
+{
+  this->timezone = timezone;
+}
+
+bool Timezone::isUTC() const
+{
+  return this->timezone.compare("Z");
+}
+
+Timezone::operator const std::string&() const
+{
+  return this->timezone;
+}
+
+}
+}
+}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/common/xsd_types/YearMonthDuration.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/common/xsd_types/YearMonthDuration.cpp
new file mode 100644
index 0000000..e6dc713
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/common/xsd_types/YearMonthDuration.cpp
@@ -0,0 +1,43 @@
+#include <BaSyx/submodel/simple/common/xsd_types/YearMonthDuration.h>
+
+
+namespace basyx {
+namespace submodel {
+namespace simple {
+
+YearMonthDuration::YearMonthDuration(int years, int months)
+{
+  this->setYears(years);
+  this->setMonths(months);
+}
+
+int YearMonthDuration::getYears() const
+{
+  return this->years;
+}
+
+int YearMonthDuration::getMonths() const
+{
+  return this->months;
+}
+
+void YearMonthDuration::setYears(const int & years)
+{
+  this->years = years;
+}
+
+void YearMonthDuration::setMonths(const int & months)
+{
+  this->years += months / 12;
+  if (months < 0)
+  {
+    this->months = 12 + (months % 12);
+    this->years -= 1;
+  }
+  else
+    this->months = months % 12;
+}
+
+}
+}
+}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/dataspecification/DataSpecification.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/dataspecification/DataSpecification.cpp
index 3feff85..7a54e61 100644
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/dataspecification/DataSpecification.cpp
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/dataspecification/DataSpecification.cpp
@@ -36,11 +36,16 @@
 	return this->ident.getDescription();
 }
 
-const IReferable * const DataSpecification::getParent() const
+IReferable * DataSpecification::getParent() const
 {
 	return this->ident.getParent();
 }
 
+void DataSpecification::setParent(IReferable * parent)
+{
+	this->setParent(parent);
+}
+
 const AdministrativeInformation & DataSpecification::getAdministrativeInformation() const
 {
 	return this->ident.getAdministrativeInformation();
@@ -71,6 +76,11 @@
   this->ident.setCategory(category);
 }
 
+simple::Reference DataSpecification::getReference() const
+{
+	return this->ident.getReference();
+};
+
 
 }
 }
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/parts/ConceptDescription.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/parts/ConceptDescription.cpp
index 8e231c8..5abbfb5 100644
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/parts/ConceptDescription.cpp
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/parts/ConceptDescription.cpp
@@ -5,7 +5,7 @@
 
 
 ConceptDescription::ConceptDescription(const std::string & idShort, const Identifier & identifier)
-	: Identifiable{idShort, identifier}
+	: identifiable(idShort, identifier)
 {}
 
 const api::IElementContainer<api::IDataSpecification> & ConceptDescription::getEmbeddedDataSpecification() const
@@ -38,3 +38,64 @@
 {
 	return this->dataSpec.getDataSpecificationReference();
 }
+
+
+const std::string & ConceptDescription::getIdShort() const
+{
+	return this->identifiable.getIdShort();
+}
+
+const std::string * const ConceptDescription::getCategory() const
+{
+	return this->identifiable.getCategory();
+};
+
+void ConceptDescription::setCategory(const std::string & category)
+{
+	this->identifiable.setCategory(category);
+}
+
+LangStringSet & ConceptDescription::getDescription()
+{
+	return this->identifiable.getDescription();
+}
+
+const LangStringSet & ConceptDescription::getDescription() const
+{
+	return this->identifiable.getDescription();
+}
+
+api::IReferable * ConceptDescription::getParent() const
+{
+	return this->identifiable.getParent();
+}
+
+void ConceptDescription::setParent(api::IReferable * parent)
+{
+	this->identifiable.setParent(parent);
+}
+
+const AdministrativeInformation & ConceptDescription::getAdministrativeInformation() const
+{
+	return this->identifiable.getAdministrativeInformation();
+}
+
+AdministrativeInformation & ConceptDescription::getAdministrativeInformation()
+{
+	return this->identifiable.getAdministrativeInformation();
+}
+
+Identifier ConceptDescription::getIdentification() const
+{
+	return this->identifiable.getIdentification();
+}
+
+bool ConceptDescription::hasAdministrativeInformation() const
+{
+	return this->identifiable.hasAdministrativeInformation();
+};
+
+simple::Reference ConceptDescription::getReference() const
+{
+	return this->identifiable.getReference();
+};
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/parts/ConceptDictionary.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/parts/ConceptDictionary.cpp
index db4fd10..1d6c462 100644
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/parts/ConceptDictionary.cpp
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/parts/ConceptDictionary.cpp
@@ -7,21 +7,61 @@
 using namespace basyx::submodel::api;
 
 ConceptDictionary::ConceptDictionary(const std::string & idShort)
-  : conecpt_descriptions{}
-  , Referable(idShort)
+  : conceptDescriptions()
+  , referable(idShort)
 {}
 
 const api::IElementContainer<api::IConceptDescription> & ConceptDictionary::getConceptDescriptions() const
 {
-  return this->conecpt_descriptions;
+  return this->conceptDescriptions;
 }
 
 void ConceptDictionary::addConceptDescription(std::unique_ptr<ConceptDescription> description)
 {
-  this->conecpt_descriptions.addElement(std::move(description));
+  this->conceptDescriptions.addElement(std::move(description));
 }
 
+const std::string & ConceptDictionary::getIdShort() const
+{
+	return this->referable.getIdShort();
+}
+
+const std::string * const ConceptDictionary::getCategory() const
+{
+	return this->referable.getCategory();
+};
+
+void ConceptDictionary::setCategory(const std::string & category)
+{
+	this->referable.setCategory(category);
+}
+
+LangStringSet & ConceptDictionary::getDescription()
+{
+	return this->referable.getDescription();
+}
+
+const LangStringSet & ConceptDictionary::getDescription() const
+{
+	return this->referable.getDescription();
+}
+
+IReferable * ConceptDictionary::getParent() const
+{
+	return this->referable.getParent();
+}
+
+void ConceptDictionary::setParent(IReferable * parent)
+{
+	this->referable.setParent(parent);
+}
+
+simple::Reference ConceptDictionary::getReference() const
+{
+	return this->referable.getReference();
+};
+
 
 }
 }
-}
+}
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/parts/View.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/parts/View.cpp
index 4968cb6..fb3720f 100644
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/parts/View.cpp
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/parts/View.cpp
@@ -3,8 +3,9 @@
 using namespace basyx::submodel;
 using namespace basyx::submodel::simple;
 
-View::View(const std::string &idShort, const Referable *parent)
-  : Referable(idShort, parent)
+View::View(const std::string &idShort, Referable * parent)
+  : referable(idShort, parent)
+  , dataSpec()
 {}
 
 const api::IElementContainer<api::IReferable> & View::getContainedElements() const
@@ -25,4 +26,55 @@
 void View::setSemanticId(const api::IReference &reference)
 {
   this->semanticId = reference;
-}
\ No newline at end of file
+}
+
+void View::addDataSpecification(const simple::Reference & reference)
+{
+	this->dataSpec.addDataSpecification(reference);
+}
+
+const std::vector<simple::Reference> View::getDataSpecificationReference() const
+{
+	return this->dataSpec.getDataSpecificationReference();
+}
+
+const std::string & View::getIdShort() const
+{
+	return this->referable.getIdShort();
+}
+
+const std::string * const View::getCategory() const
+{
+	return this->referable.getCategory();
+};
+
+void View::setCategory(const std::string & category)
+{
+	this->referable.setCategory(category);
+};
+
+LangStringSet & View::getDescription()
+{
+	return this->referable.getDescription();
+}
+
+const LangStringSet & View::getDescription() const
+{
+	return this->referable.getDescription();
+}
+
+api::IReferable * View::getParent() const
+{
+	return this->referable.getParent();
+}
+
+void View::setParent(IReferable * parent)
+{
+	this->referable.setParent(parent);
+}
+
+simple::Reference View::getReference() const
+{
+	return this->referable.getReference();
+};
+
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/qualifier/AdministrativeInformation.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/qualifier/AdministrativeInformation.cpp
index e43f7f3..4b97bed 100644
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/qualifier/AdministrativeInformation.cpp
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/qualifier/AdministrativeInformation.cpp
@@ -5,14 +5,17 @@
 namespace simple {
 
 AdministrativeInformation::AdministrativeInformation()
-{
-
-};
+{};
 
 AdministrativeInformation::AdministrativeInformation(const std::string & version, const std::string & revision)
-{
+  : version{version}
+  , revision{revision}
+{};
 
-};
+AdministrativeInformation::AdministrativeInformation(const api::IAdministrativeInformation &other)
+    : revision{*other.getRevision()}
+    , version{*other.getVersion()}
+{}
 
 void AdministrativeInformation::setVersion(const std::string & version)
 {
@@ -24,24 +27,20 @@
 	this->revision = revision;
 }
 
-std::string AdministrativeInformation::getVersion() const
+const std::string * const AdministrativeInformation::getVersion() const
 {
-	return version;
+  if (this->version.empty())
+    return nullptr;
+
+  return &this->version;
 }
 
-std::string AdministrativeInformation::getRevision() const
+const std::string * const AdministrativeInformation::getRevision() const
 {
-	return revision;
-}
+  if (this->revision.empty())
+    return nullptr;
 
-void AdministrativeInformation::addDataSpecification(const Reference & reference)
-{
-	this->hasDataSpecification.addDataSpecification(reference);
-}
-
-const std::vector<Reference> AdministrativeInformation::getDataSpecificationReference() const
-{
-	return this->hasDataSpecification.getDataSpecificationReference();
+  return &this->revision;
 }
 
 }
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/qualifier/Identifiable.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/qualifier/Identifiable.cpp
index cbbe16f..8ba4d7a 100644
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/qualifier/Identifiable.cpp
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/qualifier/Identifiable.cpp
@@ -12,9 +12,7 @@
   : Referable(other)
   , identifier(other.getIdentification().getIdType(), other.getIdentification().getId())
   , administrativeInformation(other.getAdministrativeInformation())
-{
-
-}
+{}
 
 bool Identifiable::hasAdministrativeInformation() const noexcept
 { 
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/qualifier/Referable.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/qualifier/Referable.cpp
index bbfd956..ed52a8d 100644
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/qualifier/Referable.cpp
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/qualifier/Referable.cpp
@@ -4,7 +4,7 @@
 using namespace basyx::submodel::simple;
 using namespace basyx::submodel::api;
 
-Referable::Referable(const std::string & idShort, const Referable * parent)
+Referable::Referable(const std::string & idShort, Referable * parent)
 	: idShort(idShort)
 	, parent(parent)
 {}
@@ -49,11 +49,16 @@
 	this->category = category;
 }
 
-const IReferable * const Referable::getParent() const
+IReferable * Referable::getParent() const
 {
 	return this->parent;
 };
 
+void Referable::setParent(IReferable * parent)
+{
+	this->parent = parent;
+};
+
 bool Referable::hasParent() const noexcept
 {
 	return this->parent != nullptr;
@@ -67,4 +72,28 @@
 bool Referable::hasCategory() const noexcept 
 {
 	return !this->category.empty();
+}
+
+Reference Referable::getReference() const
+{
+	auto key = simple::Key(KeyElements::AssetAdministrationShell, true, KeyType::IdShort, this->getIdShort());
+
+	if (this->getParent() == nullptr)
+		return simple::Reference(key);
+
+	auto reference = this->getParent()->getReference();
+
+	reference.addKey(key);
+
+	return reference;
+}
+
+basyx::submodel::KeyElements Referable::getKeyElementType() const
+{
+	return basyx::submodel::KeyElements::Unknown;
+}
+
+basyx::submodel::simple::Key Referable::getKey(bool local) const
+{
+	return basyx::submodel::simple::Key(this->getKeyElementType(), local, this->getKeyType(), this->getIdShort());
 }
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/reference/Key.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/reference/Key.cpp
index 4888880..8e21b0e 100644
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/reference/Key.cpp
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/reference/Key.cpp
@@ -41,6 +41,16 @@
 		&& this->value != other.value;
 };
 
+bool Key::isModelKey() const noexcept
+{
+	return this->idType != basyx::submodel::KeyType::IdShort;
+};
+
+bool Key::isGlobalKey() const noexcept
+{
+	return this->type != basyx::submodel::KeyElements::GlobalReference;
+};
+
 }
 }
 }
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/reference/Reference.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/reference/Reference.cpp
index d3ede76..3f6ab96 100644
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/reference/Reference.cpp
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/reference/Reference.cpp
@@ -32,14 +32,14 @@
 {
 };
 
-Reference Reference::FromIdentifiable(KeyElements keyElementType, const IIdentifiable & identifiable)
-{
-	return Reference(
-		Key(keyElementType,
-			true,
-			static_cast<KeyType>(identifiable.getIdentification().getIdType()),
-			identifiable.getIdentification().getId()) );
-};
+//Reference Reference::FromIdentifiable(KeyElements keyElementType, const IIdentifiable & identifiable)
+//{
+//	return Reference(
+//		Key(keyElementType,
+//			true,
+//			static_cast<KeyType>(identifiable.getIdentification().getIdType()),
+//			identifiable.getIdentification().getId()) );
+//};
 
 std::vector<Key> Reference::getKeys() const
 {
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/submodelelement/SubmodelElement.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/submodelelement/SubmodelElement.cpp
index 766d1f1..36cc77e 100644
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/submodelelement/SubmodelElement.cpp
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/submodelelement/SubmodelElement.cpp
@@ -16,7 +16,7 @@
 	return this->semanticId;
 };
 
-void SubmodelElement::setSemanticId(Reference semanticId)
+void SubmodelElement::setSemanticId(const api::IReference & semanticId)
 {
 	this->semanticId = semanticId;
 };
@@ -36,6 +36,11 @@
 	return this->referable.getIdShort();
 }
 
+void SubmodelElement::setCategory(const std::string &category)
+{
+  this->referable.setCategory(category);
+}
+
 const std::string * const SubmodelElement::getCategory() const
 {
 	return this->referable.getCategory();
@@ -51,12 +56,52 @@
 	return this->referable.getDescription();
 }
 
-const IReferable * const SubmodelElement::getParent() const
+IReferable * SubmodelElement::getParent() const
 {
 	return this->referable.getParent();
 }
 
+void SubmodelElement::setParent(IReferable * parent)
+{
+	this->setParent(parent);
+};
+
 ModelingKind SubmodelElement::getKind() const
 {
 	return this->kind;
-}
\ No newline at end of file
+}
+
+void SubmodelElement::addFormula(const api::IFormula &formula)
+{
+  this->qualifiable.addFormula(formula);
+}
+
+void SubmodelElement::addQualifier(const api::IQualifier &qualifier)
+{
+  this->qualifiable.addQualifier(qualifier);
+}
+
+std::vector<Qualifier> SubmodelElement::getQualifiers() const
+{
+  return this->qualifiable.getQualifiers();
+}
+
+std::vector<Formula> SubmodelElement::getFormulas() const
+{
+  return this->qualifiable.getFormulas();
+}
+
+ModelTypes SubmodelElement::GetModelType() const
+{
+  return this->modelType;
+}
+
+Key SubmodelElement::getKey(bool local) const 
+{
+	return this->referable.getKey(local);
+}
+
+simple::Reference SubmodelElement::getReference() const
+{
+	return this->referable.getReference();
+}
diff --git a/sdks/c++/basys.sdk.cc/src/utility/CMakeLists.txt b/sdks/c++/basys.sdk.cc/src/utility/CMakeLists.txt
index 4227da3..2015252 100644
--- a/sdks/c++/basys.sdk.cc/src/utility/CMakeLists.txt
+++ b/sdks/c++/basys.sdk.cc/src/utility/CMakeLists.txt
@@ -15,8 +15,10 @@
 set_target_properties(${BASYX_UTIL_LIB_SUFFIX} PROPERTIES SOVERSION ${BASYX_PACKAGE_VERSION_MAJOR})
 set_target_properties(${BASYX_UTIL_LIB_SUFFIX} PROPERTIES PREFIX "${CMAKE_STATIC_LIBRARY_PREFIX}${PROJECT_SHORTNAME}")
 target_include_directories(${BASYX_UTIL_LIB_SUFFIX}
-INTERFACE ${CMAKE_INSTALL_PREFIX}/include
-       ${CMAKE_INSTALL_PREFIX}/include/${PROJECT_SHORTNAME})
+	PUBLIC 
+	    $<BUILD_INTERFACE:${BASYX_INCLUDE_DIR}>  
+		$<INSTALL_INTERFACE:${CMAKE_INSTALL_PREFIX}/include>
+)
 
 target_sources(${BASYX_UTIL_LIB_SUFFIX}
     PRIVATE
@@ -41,7 +43,15 @@
 add_library(basyx::util ALIAS ${BASYX_UTIL_LIB_SUFFIX})
 add_library(${PROJECT_SHORTNAME}::${BASYX_UTIL_LIB_SUFFIX} ALIAS ${BASYX_UTIL_LIB_SUFFIX})
 
-diagnostics_print(${BASYX_UTIL_LIB_SUFFIX})
+if(BASYX_IS_SUBMODULE)
+	set_target_properties(${BASYX_UTIL_LIB_SUFFIX} PROPERTIES FOLDER BaSyx)
+endif()
+
+if(BASYX_VERBOSE_CMAKE_OUTPUT)
+	diagnostics_print(${BASYX_UTIL_LIB_SUFFIX})
+endif()
+
+build_source_group(${BASYX_UTIL_LIB_SUFFIX})
 
 ###############################################
 ###           Install section               ###
diff --git a/sdks/c++/basys.sdk.cc/src/vab/CMakeLists.txt b/sdks/c++/basys.sdk.cc/src/vab/CMakeLists.txt
index 549a9e0..a3fedf1 100644
--- a/sdks/c++/basys.sdk.cc/src/vab/CMakeLists.txt
+++ b/sdks/c++/basys.sdk.cc/src/vab/CMakeLists.txt
@@ -15,8 +15,10 @@
 set_target_properties(${BASYX_VAB_LIB_SUFFIX} PROPERTIES SOVERSION ${BASYX_PACKAGE_VERSION_MAJOR})
 set_target_properties(${BASYX_VAB_LIB_SUFFIX} PROPERTIES PREFIX "${CMAKE_STATIC_LIBRARY_PREFIX}${PROJECT_SHORTNAME}")
 target_include_directories(${BASYX_VAB_LIB_SUFFIX}
-INTERFACE ${CMAKE_INSTALL_PREFIX}/include
-       ${CMAKE_INSTALL_PREFIX}/include/${PROJECT_SHORTNAME})
+	PUBLIC 
+	    $<BUILD_INTERFACE:${BASYX_INCLUDE_DIR}>  
+		$<INSTALL_INTERFACE:${CMAKE_INSTALL_PREFIX}/include>
+)
 
 if(${BASYX_DEBUG_PRINT_FRAMES})
     target_compile_definitions(${BASYX_VAB_LIB_SUFFIX} PUBLIC PRINT_FRAME)
@@ -68,7 +70,15 @@
 add_library(basyx::vab ALIAS ${BASYX_VAB_LIB_SUFFIX})
 add_library(${PROJECT_SHORTNAME}::${BASYX_VAB_LIB_SUFFIX} ALIAS ${BASYX_VAB_LIB_SUFFIX})
 
-diagnostics_print(${BASYX_VAB_LIB_SUFFIX})
+if(BASYX_IS_SUBMODULE)
+	set_target_properties(${BASYX_VAB_LIB_SUFFIX} PROPERTIES FOLDER BaSyx)
+endif()
+
+if(BASYX_VERBOSE_CMAKE_OUTPUT)
+	diagnostics_print(${BASYX_VAB_LIB_SUFFIX})
+endif()
+
+build_source_group(${BASYX_VAB_LIB_SUFFIX})
 
 ###############################################
 ###           Install section               ###
diff --git a/sdks/c++/basys.sdk.cc/src/vab/vab/backend/connector/native/BaSyxConnector.cpp b/sdks/c++/basys.sdk.cc/src/vab/vab/backend/connector/native/BaSyxConnector.cpp
index 8924014..1f4e891 100644
--- a/sdks/c++/basys.sdk.cc/src/vab/vab/backend/connector/native/BaSyxConnector.cpp
+++ b/sdks/c++/basys.sdk.cc/src/vab/vab/backend/connector/native/BaSyxConnector.cpp
@@ -54,10 +54,16 @@
 		return basyx::object::make_error(basyx::object::error::MalformedRequest, "invalid frame received");
 	};
 
-	auto entityWrapper = nlohmann::json::parse(response_frame.getFirstValue());
+	auto firstField = response_frame.getFirstValue();
+	if (!firstField.empty())
+	{
+		auto entityWrapper = nlohmann::json::parse(response_frame.getFirstValue());
 
-	auto value = basyx::vab::EntityWrapper::from_json(entityWrapper);
-	return value;
+		auto value = basyx::vab::EntityWrapper::from_json(entityWrapper);
+		return value;
+	};
+
+	return basyx::object::make_null();
 };
 
 basyx::object NativeConnector::basysSet(std::string const& path, const basyx::object & newValue)
@@ -111,11 +117,11 @@
 	log.trace("    msg: 0x{0:x}", (std::size_t)msg);
 	log.trace("    size: {}", size);
 
-	CoderTools::setInt32(msg, 0, size);
+	CoderTools::setInt32(msg, 0, static_cast<uint32_t>(size));
 	size += BASYX_FRAMESIZE_SIZE;
 
 	log.debug("Sending {} bytes.", size);
-	int sent_bytes = this->socket.Send(basyx::net::make_buffer(msg, size));
+	auto sent_bytes = this->socket.Send(basyx::net::make_buffer(msg, size));
 	log.debug("Sent {} bytes.", sent_bytes);
 
 	if (sent_bytes < 0) {
@@ -130,7 +136,7 @@
 	log.trace("    data: 0x{0:x}", (std::size_t)data);
 
 	// recv(data, DEFAULT_BUFFER_LENGTH, 0);
-	int recv_bytes = this->socket.Receive(basyx::net::make_buffer(data, default_buffer_length));
+	auto recv_bytes = this->socket.Receive(basyx::net::make_buffer(data, default_buffer_length));
 
 	log.debug("Received {} bytes.", recv_bytes);
 
diff --git a/sdks/c++/basys.sdk.cc/src/vab/vab/provider/VABModelProvider.cpp b/sdks/c++/basys.sdk.cc/src/vab/vab/provider/VABModelProvider.cpp
index 10b2a67..387db10 100644
--- a/sdks/c++/basys.sdk.cc/src/vab/vab/provider/VABModelProvider.cpp
+++ b/sdks/c++/basys.sdk.cc/src/vab/vab/provider/VABModelProvider.cpp
@@ -71,7 +71,7 @@
 
 	// Check empty paths
 	if (vabPath.isEmpty()) {
-		// If path is empty, replace parenet element, but only if it doesn't exist
+		// If path is empty, replace parent element, but only if it does already exist
 		if (!elements.IsNull()) {
 			elements = newValue;
 			return basyx::object::error::None;
@@ -87,7 +87,7 @@
 	// Only write values, that already exist
 	auto thisElement = parentElement.getProperty(propertyName);
 
-	if (!parentElement.IsNull()/* && !thisElement.IsNull()*/) {
+	if (!parentElement.IsNull() && !thisElement.IsError() ) {
 		parentElement.insertKey(propertyName, newValue, true);
 		return basyx::object::error::None;
 	}
@@ -150,7 +150,7 @@
 	core::VABPath vabPath{ path };
 
 	if (vabPath.isEmpty())
-		return basyx::object::error::PropertyNotFound;
+		return basyx::object::error::MalformedRequest;
 
 	// Find parent & name of element
 	auto parentElement = this->getParentElement(path);
@@ -163,7 +163,8 @@
 
 		if (!childElement.IsNull()) {
 			//handler.DeleteValue(childElement, deletedValue);
-			childElement.remove(deletedValue);
+			if (!childElement.remove(deletedValue))
+				return basyx::object::error::MalformedRequest;
 			return basyx::object::error::None;
 		}
 	}
diff --git a/sdks/c++/basys.sdk.cc/src/vab/vab/provider/native/frame/BaSyxNativeFrameProcessor.cpp b/sdks/c++/basys.sdk.cc/src/vab/vab/provider/native/frame/BaSyxNativeFrameProcessor.cpp
index 9667497..eb3c1f2 100644
--- a/sdks/c++/basys.sdk.cc/src/vab/vab/provider/native/frame/BaSyxNativeFrameProcessor.cpp
+++ b/sdks/c++/basys.sdk.cc/src/vab/vab/provider/native/frame/BaSyxNativeFrameProcessor.cpp
@@ -44,6 +44,8 @@
 		return processDelete(frame);
 	case BaSyxCommand::Invoke:
 		return processInvoke(frame);
+        default:
+                break;
 	}
 
 	return Frame{};
diff --git a/sdks/c++/basys.sdk.cc/tests/CMakeLists.txt b/sdks/c++/basys.sdk.cc/tests/CMakeLists.txt
index 07135d7..350df48 100644
--- a/sdks/c++/basys.sdk.cc/tests/CMakeLists.txt
+++ b/sdks/c++/basys.sdk.cc/tests/CMakeLists.txt
@@ -24,8 +24,8 @@
 
 add_subdirectory(regression/util)
 add_subdirectory(regression/vab)
-add_subdirectory(regression/aas)
 add_subdirectory(regression/submodel)
+add_subdirectory(regression/controlcomponent)
 
 ### Integration tests ###
 
diff --git a/sdks/c++/basys.sdk.cc/tests/integration/cpp_test_connector/cpp_test_connector.cpp b/sdks/c++/basys.sdk.cc/tests/integration/cpp_test_connector/cpp_test_connector.cpp
index 0c838fe..0739dd7 100644
--- a/sdks/c++/basys.sdk.cc/tests/integration/cpp_test_connector/cpp_test_connector.cpp
+++ b/sdks/c++/basys.sdk.cc/tests/integration/cpp_test_connector/cpp_test_connector.cpp
@@ -89,44 +89,50 @@
 };
 
 #define HOST "127.0.0.1"
+#define PORT "8383"
 
-int test() 
+std::string host(HOST);
+std::string port(PORT);
+
+int connector_run(const std::string & host, const std::string & port) 
 {
-	//std::string host;
-	//if (argc > 1)
-	//	host = argv[1];
-	//else
-	//	host = HOST;
-
-	std::string host = HOST;
-
-   	auto connector = util::make_unique<vab::connector::native::NativeConnector>(host, 7001);
+   	auto connector = util::make_unique<vab::connector::native::NativeConnector>(host, port);
 
 	auto provider = ConnectedModelProvider(connector.get());
 
+	connector->basysInvoke("/reset", 0);
 	basyx::tests::regression::vab::snippet::MapRead::test(&provider);
+	
+	connector->basysInvoke("/reset", 0);
 	basyx::tests::regression::vab::snippet::MapUpdate::test(&provider);
+	
+	connector->basysInvoke("/reset", 0);	
 	basyx::tests::regression::vab::snippet::MapCreateDelete::test(&provider);
+	
+	connector->basysInvoke("/reset", 0);
 	basyx::tests::regression::vab::snippet::TestCollectionProperty::test(&provider);
+	
+	connector->basysInvoke("/reset", 0);
 	basyx::tests::regression::vab::snippet::MapInvoke::test(&provider);
-
-	//auto get = connector->basysGet("primitives/integer");
-
-	//connector->basysSet("primitives/integer", 20);
-
-	//auto get2 = connector->basysGet("primitives/integer");
-
-	//auto inv = connector->basysInvoke("operations/complex", basyx::object::object_list_t{ 1,2 });
+	
+	connector->basysInvoke("/reset", 0);
 
 	return 0;
 };
 
 TEST(Test_Case, Test)
 {
-	test();
+	connector_run(host, port);
 };
 
-int main(int argc, char **argv) {
+int main(int argc, char **argv) 
+{
+	if (argc > 1)
+		host = argv[1];
+
+	if (argc > 2)
+		port = argv[2];
+
 	// Init gtest framework
 	::testing::InitGoogleTest(&argc, argv);
 
diff --git a/sdks/c++/basys.sdk.cc/tests/integration/cpp_test_server/cpp_test_server.cpp b/sdks/c++/basys.sdk.cc/tests/integration/cpp_test_server/cpp_test_server.cpp
index fb95f67..b10494a 100644
--- a/sdks/c++/basys.sdk.cc/tests/integration/cpp_test_server/cpp_test_server.cpp
+++ b/sdks/c++/basys.sdk.cc/tests/integration/cpp_test_server/cpp_test_server.cpp
@@ -1,24 +1,42 @@
-#include <BaSyx/vab/provider/hashmap/VABHashmapProvider.h>
 #include <BaSyx/server/TCPServer.h>
+#include <BaSyx/vab/provider/hashmap/VABHashmapProvider.h>
 #include <vab/stub/elements/SimpleVABElement.h>
 
 using namespace basyx;
 
-int main(int argc, char * argv[])
+class IntegrationTestModelProvider : public vab::provider::VABModelProvider {
+public:
+    void Reset()
+    {
+        this->elements = tests::support::make_simple_vab_element();
+    }
+
+    virtual basyx::object invokeOperation(const std::string& path, basyx::object parameters) override
+    {
+        log.info("[Integration] reset called");
+        if (path == "reset") {
+            Reset();
+            return basyx::object::make_null();
+        };
+
+        return VABModelProvider::invokeOperation(path, parameters);
+    };
+};
+
+int main(int argc, char* argv[])
 {
-	int port = 7001;
+    int port = 6000;
 
-	if (argc > 1)
-		port = std::atoi(argv[1]);
+    if (argc > 1)
+        port = std::atoi(argv[1]);
 
-	vab::provider::VABModelProvider modelProvider{ tests::support::make_simple_vab_element() };
-	server::TCPServer<vab::provider::VABModelProvider> tcpServer{ &modelProvider, port };
+    IntegrationTestModelProvider modelProvider;
+    modelProvider.Reset();
+	server::TCPServer<IntegrationTestModelProvider> tcpServer { &modelProvider, port };
 
+    while (true) {
+        tcpServer.update();
+    };
 
-	while (true)
-	{
-		tcpServer.update();
-	};
-
-	return 0;
+    return 0;
 };
diff --git a/sdks/c++/basys.sdk.cc/tests/regression/controlcomponent/CMakeLists.txt b/sdks/c++/basys.sdk.cc/tests/regression/controlcomponent/CMakeLists.txt
new file mode 100644
index 0000000..f7b541d
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/tests/regression/controlcomponent/CMakeLists.txt
@@ -0,0 +1,20 @@
+#####################################################
+###             tests_controlcomponent            ###
+#####################################################
+
+cmake_minimum_required(VERSION 3.1.0)
+
+project(tests_controlcomponent)
+
+add_executable(${PROJECT_NAME})
+
+target_sources(${PROJECT_NAME}
+  PRIVATE
+	test_ControlComponent.cpp
+)
+
+target_include_directories(${PROJECT_NAME} PUBLIC ${PROJECT_SOURCE_DIR})
+target_link_libraries(${PROJECT_NAME} basyx::util basyx::shared lib::gtest basyx::vab tests::support basyx::controlcomponent tests::main)
+gtest_discover_tests(${PROJECT_NAME})
+
+diagnostics_print(${PROJECT_NAME})
diff --git a/sdks/c++/basys.sdk.cc/tests/regression/controlcomponent/support/ControlComponentChangeListenerMock.hpp b/sdks/c++/basys.sdk.cc/tests/regression/controlcomponent/support/ControlComponentChangeListenerMock.hpp
new file mode 100644
index 0000000..ac54b44
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/tests/regression/controlcomponent/support/ControlComponentChangeListenerMock.hpp
@@ -0,0 +1,101 @@
+#ifndef BASYX_TESTING_SUPPORT_CONTROLCOMPONENT_CONTROLCOMPONENTCHANGELISTENER_MOCK_H_
+#define BASYX_TESTING_SUPPORT_CONTROLCOMPONENT_CONTROLCOMPONENTCHANGELISTENER_MOCK_H_
+
+#include <gtest/gtest.h>
+#include <BaSyx/controlcomponent/interfaces/IControlComponentChangeListener.h>
+
+using namespace basyx::controlcomponent;
+
+class ControlComponentChangeListenerMock : public IControlComponentChangeListener
+{
+public:
+  int unique_id = 0;
+
+  int call_counter_onVariableChange = 0;
+  int call_counter_onNewOccupier = 0;
+  int call_counter_onNewOccupationState = 0;
+  int call_counter_onLastOccupier = 0;
+  int call_counter_onChangedExecutionMode = 0;
+  int call_counter_onChangedExecutionState = 0;
+  int call_counter_onChangedOperationMode = 0;
+  int call_counter_onChangedWorkState = 0;
+  int call_counter_onChangedErrorState = 0;
+  int call_counter_onChangedPrevError = 0;
+  int call_counter_getUniqueID = 0;
+
+  ControlComponentChangeListenerMock(int id) : unique_id{id} {}
+  ControlComponentChangeListenerMock() {}
+
+  void onVariableChange(const std::string &varName, basyx::object newValue) override
+  {
+    call_counter_onVariableChange++;
+  }
+
+  void onNewOccupier(const std::string &occupierId) override
+  {
+    call_counter_onNewOccupier++;
+  }
+
+  void onNewOccupationState(basyx::controlcomponent::OccupationState state) override
+  {
+    call_counter_onNewOccupationState++;
+  }
+
+  void onLastOccupier(const std::string &lastOccupierId) override
+  {
+    call_counter_onLastOccupier++;
+  }
+
+  void onChangedExecutionMode(basyx::controlcomponent::ExecutionMode newExecutionMode) override
+  {
+    call_counter_onChangedExecutionMode++;
+  }
+
+  void onChangedExecutionState(basyx::controlcomponent::ExecutionState newExecutionState) override
+  {
+    call_counter_onChangedExecutionState++;
+  }
+
+  void onChangedOperationMode(const std::string &newOperationMode) override
+  {
+    call_counter_onChangedOperationMode++;
+  }
+
+  void onChangedWorkState(const std::string &newWorkState) override
+  {
+    call_counter_onChangedWorkState++;
+  }
+
+  void onChangedErrorState(const std::string &newWorkState) override
+  {
+    call_counter_onChangedErrorState++;
+  }
+
+  void onChangedPrevError(const std::string &newWorkState) override
+  {
+    call_counter_onChangedPrevError++;
+  }
+
+  int getUniqueID() override
+  {
+    call_counter_getUniqueID++;
+    return unique_id;
+  }
+
+  void reset()
+  {
+    call_counter_onVariableChange = 0;
+    call_counter_onNewOccupier = 0;
+    call_counter_onNewOccupationState = 0;
+    call_counter_onLastOccupier = 0;
+    call_counter_onChangedExecutionMode = 0;
+    call_counter_onChangedExecutionState = 0;
+    call_counter_onChangedOperationMode = 0;
+    call_counter_onChangedWorkState = 0;
+    call_counter_onChangedErrorState = 0;
+    call_counter_onChangedPrevError = 0;
+    call_counter_getUniqueID = 0;  
+  }
+};
+
+#endif
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/tests/regression/controlcomponent/test_ControlComponent.cpp b/sdks/c++/basys.sdk.cc/tests/regression/controlcomponent/test_ControlComponent.cpp
new file mode 100644
index 0000000..ea1162e
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/tests/regression/controlcomponent/test_ControlComponent.cpp
@@ -0,0 +1,369 @@
+#include <gtest/gtest.h>
+
+#include <BaSyx/controlcomponent/map/ControlComponent.h>
+#include <BaSyx/controlcomponent/enumerations/ExecutionOrder.h>
+#include <BaSyx/controlcomponent/simple/ControlComponent.h>
+#include "support/ControlComponentChangeListenerMock.hpp"
+
+using namespace basyx::controlcomponent;
+
+using ImplTypes = ::testing::Types<
+  simple::ControlComponent,
+  map::ControlComponent
+>;
+
+template<class Impl>
+class ControlComponentTest: public ::testing::Test{
+protected:
+	std::unique_ptr<IControlComponent> control_component;
+	std::shared_ptr<ControlComponentChangeListenerMock> change_listener, change_listener_2;
+protected:
+	void SetUp() override
+	{
+	  this->control_component = util::make_unique<Impl>();
+	    this->change_listener = std::make_shared<ControlComponentChangeListenerMock>();
+      this->change_listener_2 = std::make_shared<ControlComponentChangeListenerMock>(2);
+
+	  this->control_component->addControlComponentChangeListener(change_listener);
+    this->control_component->addControlComponentChangeListener(change_listener_2);
+	}
+
+	void TearDown() override
+	{
+	}
+};
+
+TYPED_TEST_CASE(ControlComponentTest, ImplTypes);
+
+TYPED_TEST(ControlComponentTest, TestListener)
+{
+  this->control_component->removeControlComponentChangeListener(this->change_listener);
+  // getUniqueID should have been called twice (see SetUp() above)
+  ASSERT_EQ(2, this->change_listener->call_counter_getUniqueID);
+
+  //only teh second change listener should have been notified
+  this->control_component->setLastOccupierID("");
+  ASSERT_EQ(0, this->change_listener->call_counter_onLastOccupier);
+  ASSERT_EQ(1, this->change_listener_2->call_counter_onLastOccupier);
+}
+
+TYPED_TEST(ControlComponentTest, TestAddClearOrder)
+{
+  //intially the list should be empty
+  const std::vector<std::string> & list = this->control_component->getOrderList();
+  ASSERT_EQ(list.size(), 0);
+
+  //add some orders
+  this->control_component->addOrder("order_1");
+  this->control_component->addOrder("order_2");
+
+  //check if they are in list
+  ASSERT_EQ(list.size(), 2);
+
+  //clear list
+  this->control_component->clearOrder();
+  ASSERT_EQ(list.size(), 0);
+}
+
+/*TEST_F(MapTest, TestPut)
+{
+  this->control_component->addControlComponentChangeListener(this->change_listener_2);
+
+  this->control_component->put("key", "test");
+  //key value pair should be in map
+  ASSERT_EQ("test", this->control_component->getMap().getProperty("key").GetStringContent());
+  //changeListeners onVariableChange should be called for each put
+  ASSERT_EQ(1, this->change_listener->call_counter_onVariableChange);
+  ASSERT_EQ(1, this->change_listener_2->call_counter_onVariableChange);
+  this->change_listener->reset();
+  this->change_listener_2->reset();
+
+  //If key cmd and value is a valid ExecutionOrder, ExecutionState should have changed
+  this->control_component->put("cmd", ExecutionOrder_::to_string(ExecutionOrder::reset));
+  ASSERT_EQ(1, this->change_listener->call_counter_onChangedExecutionState);
+  ASSERT_EQ(1, this->change_listener_2->call_counter_onChangedExecutionState);
+  ASSERT_EQ(ExecutionState::resetting ,this->control_component->getExecutionState());
+    this->change_listener->reset();
+    this->change_listener_2->reset();
+
+  //If key is localOverwrite occupier should be local
+  this->control_component->put(ControlComponentConstants_::to_string(ControlComponentConstants::localOverwrite), "test");
+  ASSERT_EQ(1,   this->change_listener->call_counter_onNewOccupationState);
+  ASSERT_EQ(1,   this->change_listener->call_counter_onNewOccupier);
+  ASSERT_EQ(ControlComponentConstants_::to_string(ControlComponentConstants::LOCAL), this->control_component->getOccupierID());
+  ASSERT_EQ(OccupationState::local, this->control_component->getOccupationState());
+
+  this->control_component->put(ControlComponentConstants_::to_string(ControlComponentConstants::localOverwriteFree), "test");
+  ASSERT_EQ("", this->control_component->getOccupierID());
+}*/
+
+TYPED_TEST(ControlComponentTest, TestOccupationState)
+{
+  OccupationState inital = this->control_component->getOccupationState();
+  ASSERT_EQ(OccupationState::free, inital);
+
+  this->control_component->setOccupationState(OccupationState::occupied);
+  OccupationState next = this->control_component->getOccupationState();
+  ASSERT_EQ(OccupationState::occupied, next);
+  ASSERT_EQ(1,   this->change_listener->call_counter_onNewOccupationState);
+  ASSERT_EQ(1,   this->change_listener_2->call_counter_onNewOccupationState);
+}
+
+TYPED_TEST(ControlComponentTest, TestOccupierId)
+{
+  std::string initial = this->control_component->getOccupierID();
+  ASSERT_EQ(initial, "");
+
+  this->control_component->setOccupierID("Some occupier");
+  std::string id = this->control_component->getOccupierID();
+  ASSERT_EQ("Some occupier", id);
+  ASSERT_EQ(1,   this->change_listener->call_counter_onNewOccupier);
+  ASSERT_EQ(1,   this->change_listener_2->call_counter_onNewOccupier);
+}
+
+TYPED_TEST(ControlComponentTest, TestLastOccupierId)
+{
+  std::string initial = this->control_component->getLastOccupierID();
+  ASSERT_EQ(initial, "");
+
+  this->control_component->setLastOccupierID("Some last occupier");
+  std::string id = this->control_component->getLastOccupierID();
+  ASSERT_EQ("Some last occupier", id);
+  ASSERT_EQ(1,   this->change_listener->call_counter_onLastOccupier);
+  ASSERT_EQ(1,   this->change_listener_2->call_counter_onLastOccupier);
+}
+
+TYPED_TEST(ControlComponentTest, TestExecutionMode)
+{
+  ExecutionMode initial = this->control_component->getExecutionMode();
+  ASSERT_EQ(initial, ExecutionMode::Auto);
+
+  this->control_component->setExecutionMode(ExecutionMode::Reserved);
+  ExecutionMode ex_mode = this->control_component->getExecutionMode();
+  ASSERT_EQ(ex_mode, ExecutionMode::Reserved);
+  ASSERT_EQ(1,   this->change_listener->call_counter_onChangedExecutionMode);
+  ASSERT_EQ(1,   this->change_listener_2->call_counter_onChangedExecutionMode);
+}
+
+TYPED_TEST(ControlComponentTest, TestExecutionState)
+{
+  ExecutionState initial = this->control_component->getExecutionState();
+  ASSERT_EQ(initial, ExecutionState::idle);
+
+  this->control_component->setExecutionState(ExecutionState::clearing);
+  ExecutionState ex_state = this->control_component->getExecutionState();
+  ASSERT_EQ(ex_state, ExecutionState::clearing);
+  ASSERT_EQ(1,   this->change_listener->call_counter_onChangedExecutionState);
+  ASSERT_EQ(1,   this->change_listener_2->call_counter_onChangedExecutionState);
+}
+
+TYPED_TEST(ControlComponentTest, TestOperationMode)
+{
+  std::string initial = this->control_component->getOperationMode();
+  ASSERT_EQ(initial, "");
+
+  this->control_component->setOperationMode("Special operation");
+  std::string op_mode = this->control_component->getOperationMode();
+  ASSERT_EQ(op_mode, "Special operation");
+  ASSERT_EQ(1,   this->change_listener->call_counter_onChangedOperationMode);
+  ASSERT_EQ(1,   this->change_listener_2->call_counter_onChangedOperationMode);
+}
+
+TYPED_TEST(ControlComponentTest, TestCommand)
+{
+  std::string initial = this->control_component->getCommand();
+  ASSERT_EQ(initial, "");
+
+  this->control_component->setCommand("Some command");
+  std::string command = this->control_component->getCommand();
+  ASSERT_EQ(command, "Some command");
+}
+
+TYPED_TEST(ControlComponentTest, TestLocalOverwrite)
+{
+  std::string initial = this->control_component->getLocalOverwrite();
+  ASSERT_EQ(initial, "");
+
+  this->control_component->setLocalOverwrite("Some overwrite");
+  std::string command = this->control_component->getLocalOverwrite();
+  ASSERT_EQ(command, "Some overwrite");
+}
+
+TYPED_TEST(ControlComponentTest, TestLocalOverwriteFree)
+{
+  std::string initial = this->control_component->getLocalOverwriteFree();
+  ASSERT_EQ(initial, "");
+
+  this->control_component->setLocalOverwriteFree("Some overwrite free");
+  std::string command = this->control_component->getLocalOverwriteFree();
+  ASSERT_EQ(command, "Some overwrite free");
+}
+
+TYPED_TEST(ControlComponentTest, TestServiceMap)
+{
+  basyx::object service_map = this->control_component->getServiceOperationMap();
+
+  service_map.getProperty(ControlComponentConstants_::to_string(ControlComponentConstants::semiauto)).invoke();
+  ExecutionMode ex_mode = this->control_component->getExecutionMode();
+  ASSERT_EQ(ex_mode, ExecutionMode::Semiauto);
+
+  service_map.getProperty(ControlComponentConstants_::to_string(ControlComponentConstants::start)).invoke();
+  ExecutionState ex_state = this->control_component->getExecutionState();
+  ASSERT_EQ(ex_state, ExecutionState::starting);
+
+  service_map.getProperty(ControlComponentConstants_::to_string(ControlComponentConstants::bstate)).invoke();
+  std::string op_mode = this->control_component->getOperationMode();
+  ASSERT_EQ(op_mode, "BSTATE");
+}
+
+TYPED_TEST(ControlComponentTest, TestFreeControlComponent)
+{
+  basyx::object service_map = this->control_component->getServiceOperationMap();
+
+  //set occupierID and last occupierID
+  this->control_component->setOccupierID("It's me");
+  this->control_component->setLastOccupierID("It's not anymore me");
+
+  // Try to free the controlcomponent
+  basyx::object who("It's me");
+  service_map.getProperty(ControlComponentConstants_::to_string(ControlComponentConstants::free)).invoke(who);
+  ASSERT_EQ(1,   this->change_listener->call_counter_onNewOccupationState);
+  ASSERT_EQ(1,   this->change_listener_2->call_counter_onNewOccupationState);
+
+  ASSERT_EQ("It's not anymore me", this->control_component->getOccupierID());
+  OccupationState oc_state = this->control_component->getOccupationState();
+  ASSERT_EQ(oc_state, OccupationState::occupied);
+
+  // Try to free controlcomponent without permission
+  service_map.getProperty(ControlComponentConstants_::to_string(ControlComponentConstants::free)).invoke(who);
+  //should not have changed
+  ASSERT_EQ("It's not anymore me", this->control_component->getOccupierID());
+  ASSERT_EQ(2,   this->change_listener->call_counter_onNewOccupier);
+  ASSERT_EQ(2,   this->change_listener_2->call_counter_onNewOccupier);
+
+  basyx::object has_permission("It's not anymore me");
+  service_map.getProperty(ControlComponentConstants_::to_string(ControlComponentConstants::free)).invoke(has_permission);
+  // should be empty now
+  ASSERT_EQ("", this->control_component->getOccupierID());
+  // ... and free
+  oc_state = this->control_component->getOccupationState();
+  ASSERT_EQ(oc_state, OccupationState::free);
+  ASSERT_EQ(3,   this->change_listener->call_counter_onNewOccupier);
+  ASSERT_EQ(3,   this->change_listener_2->call_counter_onNewOccupier);
+}
+
+TYPED_TEST(ControlComponentTest, TestOccupyControlComponent)
+{
+  basyx::object service_map = this->control_component->getServiceOperationMap();
+
+  basyx::object who("me");
+  service_map.getProperty(ControlComponentConstants_::to_string(ControlComponentConstants::occupy)).invoke(who);
+
+  // should be occupied by "me"
+  ASSERT_EQ(who.GetStringContent(), this->control_component->getOccupierID());
+  ASSERT_EQ(OccupationState::occupied, this->control_component->getOccupationState());
+  ASSERT_EQ(1,   this->change_listener->call_counter_onNewOccupationState);
+  ASSERT_EQ(1,   this->change_listener_2->call_counter_onNewOccupationState);
+
+  //If occupied, no one else should be able to occupy component
+  basyx::object not_permitted("Someone else");
+  service_map.getProperty(ControlComponentConstants_::to_string(ControlComponentConstants::occupy)).invoke();
+  ASSERT_EQ(who.GetStringContent(), this->control_component->getOccupierID());
+  ASSERT_EQ(OccupationState::occupied, this->control_component->getOccupationState());
+  ASSERT_EQ(1,   this->change_listener->call_counter_onNewOccupier);
+  ASSERT_EQ(1,   this->change_listener_2->call_counter_onNewOccupier);
+}
+
+TYPED_TEST(ControlComponentTest, TestPriorityOccupation)
+{
+  basyx::object service_map = this->control_component->getServiceOperationMap();
+
+  basyx::object who("me");
+  service_map.getProperty(ControlComponentConstants_::to_string(ControlComponentConstants::occupy)).invoke(who);
+  basyx::object priority_occupier("priority");
+  service_map.getProperty(ControlComponentConstants_::to_string(ControlComponentConstants::priority)).invoke(priority_occupier);
+
+  //Component should be in prioirity mode, last occupier "me" and actual occupier "priority"
+  ASSERT_EQ(OccupationState::priority, this->control_component->getOccupationState());
+  ASSERT_EQ("me", this->control_component->getLastOccupierID());
+  ASSERT_EQ("priority", this->control_component->getOccupierID());
+  ASSERT_EQ(2,   this->change_listener->call_counter_onNewOccupier);
+  ASSERT_EQ(2,   this->change_listener_2->call_counter_onNewOccupier);
+
+  //"me" should not be able to free component
+  service_map.getProperty(ControlComponentConstants_::to_string(ControlComponentConstants::free)).invoke(who);
+  ASSERT_EQ("priority", this->control_component->getOccupierID());
+  ASSERT_EQ(2,   this->change_listener->call_counter_onNewOccupationState);
+  ASSERT_EQ(2,   this->change_listener_2->call_counter_onNewOccupationState);
+
+  //but "prioirity" should be
+  service_map.getProperty(ControlComponentConstants_::to_string(ControlComponentConstants::free)).invoke(priority_occupier);
+  ASSERT_EQ("me", this->control_component->getOccupierID());
+  ASSERT_EQ(OccupationState::occupied, this->control_component->getOccupationState());
+  ASSERT_EQ(3,   this->change_listener->call_counter_onNewOccupier);
+  ASSERT_EQ(3,   this->change_listener_2->call_counter_onNewOccupier);
+}
+
+TYPED_TEST(ControlComponentTest, TestFinishState)
+{
+  // test transitions according to packml state machine
+  this->control_component->setExecutionState(ExecutionState::starting);
+  this->control_component->finishState();
+  ASSERT_EQ(ExecutionState::execute, this->control_component->getExecutionState());
+  ASSERT_EQ(2,   this->change_listener->call_counter_onChangedExecutionState);
+
+  this->control_component->setExecutionState(ExecutionState::execute);
+  this->control_component->finishState();
+  ASSERT_EQ(ExecutionState::completing, this->control_component->getExecutionState());
+  ASSERT_EQ(4,   this->change_listener->call_counter_onChangedExecutionState);
+
+  this->control_component->setExecutionState(ExecutionState::completing);
+  this->control_component->finishState();
+  ASSERT_EQ(ExecutionState::complete, this->control_component->getExecutionState());
+  ASSERT_EQ(6,   this->change_listener->call_counter_onChangedExecutionState);
+
+  this->control_component->setExecutionState(ExecutionState::resetting);
+  this->control_component->finishState();
+  ASSERT_EQ(ExecutionState::idle, this->control_component->getExecutionState());
+  ASSERT_EQ(8,   this->change_listener->call_counter_onChangedExecutionState);
+
+  this->control_component->setExecutionState(ExecutionState::holding);
+  this->control_component->finishState();
+  ASSERT_EQ(ExecutionState::held, this->control_component->getExecutionState());
+  ASSERT_EQ(10,   this->change_listener->call_counter_onChangedExecutionState);
+
+  this->control_component->setExecutionState(ExecutionState::unholding);
+  this->control_component->finishState();
+  ASSERT_EQ(ExecutionState::execute, this->control_component->getExecutionState());
+  ASSERT_EQ(12,   this->change_listener->call_counter_onChangedExecutionState);
+
+  this->control_component->setExecutionState(ExecutionState::suspending);
+  this->control_component->finishState();
+  ASSERT_EQ(ExecutionState::suspended, this->control_component->getExecutionState());
+  ASSERT_EQ(14,   this->change_listener->call_counter_onChangedExecutionState);
+
+  this->control_component->setExecutionState(ExecutionState::unsuspending);
+  this->control_component->finishState();
+  ASSERT_EQ(ExecutionState::execute, this->control_component->getExecutionState());
+  ASSERT_EQ(16,   this->change_listener->call_counter_onChangedExecutionState);
+
+  this->control_component->setExecutionState(ExecutionState::stopping);
+  this->control_component->finishState();
+  ASSERT_EQ(ExecutionState::stopped, this->control_component->getExecutionState());
+  ASSERT_EQ(18,   this->change_listener->call_counter_onChangedExecutionState);
+
+  this->control_component->setExecutionState(ExecutionState::stopped);
+  this->control_component->finishState();
+  ASSERT_EQ(ExecutionState::idle, this->control_component->getExecutionState());
+  ASSERT_EQ(20,   this->change_listener->call_counter_onChangedExecutionState);
+
+  this->control_component->setExecutionState(ExecutionState::aborting);
+  this->control_component->finishState();
+  ASSERT_EQ(ExecutionState::aborted, this->control_component->getExecutionState());
+  ASSERT_EQ(22,   this->change_listener->call_counter_onChangedExecutionState);
+
+  this->control_component->setExecutionState(ExecutionState::clearing);
+  this->control_component->finishState();
+  ASSERT_EQ(ExecutionState::stopped, this->control_component->getExecutionState());
+  ASSERT_EQ(24,   this->change_listener->call_counter_onChangedExecutionState);
+}
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/tests/regression/submodel/CMakeLists.txt b/sdks/c++/basys.sdk.cc/tests/regression/submodel/CMakeLists.txt
index 3a23555..98b347c 100644
--- a/sdks/c++/basys.sdk.cc/tests/regression/submodel/CMakeLists.txt
+++ b/sdks/c++/basys.sdk.cc/tests/regression/submodel/CMakeLists.txt
@@ -11,8 +11,10 @@
 target_sources(${PROJECT_NAME}
   PRIVATE
 	api/common/test_ElementContainer.cpp
+	api/aas/test_AssetAdministrationShell.cpp
 	api/constraint/test_Formula.cpp
 	api/constraint/test_Qualifier.cpp
+	api/qualifier/test_AdministrativeInformation.cpp
 	api/qualifier/test_HasDataSpecification.cpp
 	api/qualifier/test_Identifiable.cpp
 	api/qualifier/test_Qualifiable.cpp
@@ -23,8 +25,11 @@
 	api/parts/test_ConceptDictionary.cpp
 	api/parts/test_ConceptDescription.cpp
 	api/parts/test_View.cpp
-	map/common/test_ElementContainer.cpp
+	api/property/test_Property.cpp
 	api/common/test_LangStringSet.cpp
+	api/property/test_Property.cpp
+	api/test_Submodel.cpp
+	map_v2/common/test_ElementContainer.cpp
 	map_v2/dataspecification/test_DataSpecification.cpp
 	map_v2/dataspecification/test_DataSpecificationIEC61360.cpp
 	map_v2/identifier/test_Identifier.cpp
@@ -34,4 +39,4 @@
 target_link_libraries(${PROJECT_NAME} basyx::util basyx::shared lib::gtest basyx::vab tests::support basyx::submodel tests::main)
 gtest_discover_tests(${PROJECT_NAME})
 
-diagnostics_print(${PROJECT_NAME})
\ No newline at end of file
+diagnostics_print(${PROJECT_NAME})
diff --git a/sdks/c++/basys.sdk.cc/tests/regression/submodel/api/aas/test_AssetAdministrationShell.cpp b/sdks/c++/basys.sdk.cc/tests/regression/submodel/api/aas/test_AssetAdministrationShell.cpp
new file mode 100644
index 0000000..23144ad
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/tests/regression/submodel/api/aas/test_AssetAdministrationShell.cpp
@@ -0,0 +1,51 @@
+#include <gtest/gtest.h>
+
+#include <BaSyx/submodel/api_v2/aas/IAssetAdministrationShell.h>
+#include <BaSyx/submodel/map_v2/aas/AssetAdministrationShell.h>
+#include <BaSyx/submodel/simple/aas/AssetAdministrationShell.h>
+
+#include <BaSyx/submodel/map_v2/SubModel.h>
+
+#include <BaSyx/util/util.h>
+
+using namespace basyx::submodel;
+
+using ImplTypes = ::testing::Types<
+    std::tuple<map::AssetAdministrationShell, map::Asset>,
+    std::tuple<simple::AssetAdministrationShell, simple::Asset>>;
+
+template<class Impl>
+class AssetAdministrationShellTest :public ::testing::Test {
+protected:
+  using impl_t = typename std::tuple_element<0, Impl>::type;
+  using asset_t = typename std::tuple_element<1, Impl>::type;
+
+	std::unique_ptr<api::IAssetAdministrationShell> aas;
+protected:
+	void SetUp() override
+	{
+		aas = util::make_unique<impl_t>("testAas",
+			simple::Identifier::Custom("testAas"), 
+			asset_t{ "testAsset", simple::Identifier::Custom("testAsset") }
+			);
+	}
+
+	void TearDown() override
+	{	}
+};
+
+TYPED_TEST_CASE(AssetAdministrationShellTest, ImplTypes);
+
+TYPED_TEST(AssetAdministrationShellTest, TestModelType)
+{
+	ASSERT_EQ(this->aas->GetModelType(), basyx::submodel::ModelTypes::AssetAdministrationShell);
+};
+
+TYPED_TEST(AssetAdministrationShellTest, TestAddSubmodel)
+{
+	auto submodel = this->aas->getSubmodels().template createElement<basyx::submodel::map::SubModel>("testSubmodel", simple::Identifier::Custom("testSubmodel"));
+
+	ASSERT_EQ(this->aas->getSubmodels().size(), 1);
+
+	return;
+};
diff --git a/sdks/c++/basys.sdk.cc/tests/regression/submodel/api/common/test_ElementContainer.cpp b/sdks/c++/basys.sdk.cc/tests/regression/submodel/api/common/test_ElementContainer.cpp
index 10ba5be..abd197f 100644
--- a/sdks/c++/basys.sdk.cc/tests/regression/submodel/api/common/test_ElementContainer.cpp
+++ b/sdks/c++/basys.sdk.cc/tests/regression/submodel/api/common/test_ElementContainer.cpp
@@ -52,6 +52,25 @@
 	ASSERT_EQ(propB->getValue(), 5);
 };
 
+TYPED_TEST(ElementContainerTest, TestGetByIndex)
+{
+	auto prop = util::make_unique<Property<int>>("prop1");
+	prop->setValue(5);
+
+	auto prop2 = util::make_unique<Property<float>>("prop2");
+	prop2->setValue(10.0f);
+
+	this->elementContainer->addElement(std::move(prop));
+	this->elementContainer->addElement(std::move(prop2));
+	ASSERT_EQ(this->elementContainer->size(), 2);
+
+	auto submodelElement1 = this->elementContainer->getElement(0);
+	ASSERT_TRUE(submodelElement1->getIdShort() == "prop1" || submodelElement1->getIdShort() == "prop2");
+
+	auto submodelElement2 = this->elementContainer->getElement(0);
+	ASSERT_TRUE(submodelElement2->getIdShort() == "prop1" || submodelElement2->getIdShort() == "prop2");
+};
+
 TYPED_TEST(ElementContainerTest, TestCreate)
 {
 	auto prop = this->elementContainer->template createElement<Property<int>>("testProperty");
@@ -64,62 +83,3 @@
 	ASSERT_EQ(propB->getValue(), 5);
 };
 
-/*********************************************************
- * Map implementation tests
- *********************************************************/
-
-class MapElementContainerTest : public ::testing::Test {
-protected:
-  map::ElementContainer<ISubmodelElement> elementContainer;
-protected:
-  void SetUp() override
-  {
-  }
-
-  void TearDown() override
-  {
-  }
-};
-
-TEST_F(MapElementContainerTest, TestMapImplementationCreateDeleteAfterwards)
-{
-	auto prop = this->elementContainer.createElement<Property<int>>("testProperty");
-	ASSERT_EQ(this->elementContainer.size(), 1);
-	prop->setValue(5);
-
-	// Delete in map
-	auto & objectList = this->elementContainer.getMap().Get<basyx::object::object_list_t&>();
-	objectList.clear();
-	ASSERT_EQ(this->elementContainer.size(), 0);
-	auto prop_b = this->elementContainer.getElement("testProperty");
-	ASSERT_EQ(prop_b, nullptr);
-};
-
-
-/*********************************************************
- * Simple implementation tests
- *********************************************************/
-class SimpleElementContainerTest : public ::testing::Test {
-protected:
-  simple::ElementContainer<IReferable> elementContainer;
-protected:
-  void SetUp() override
-  {}
-
-  void TearDown() override
-  {}
-};
-
-TEST_F(SimpleElementContainerTest, TestSimpleImplementationCopy)
-{
-//  std::unique_ptr<IReferable> ref = util::make_unique<simple::Referable>("testRef");
-//  ref->setCategory("testCategory");
-//  this->elementContainer.addElement(std::unique_ptr<IReferable>(ref.release()));
-//  ASSERT_EQ(this->elementContainer.size(), 1);
-//
-//  simple::ElementContainer<IReferable> elementContainer2(std::move(elementContainer));
-//  auto prop2 = dynamic_cast<simple::Referable*>(elementContainer2.getElement("testRef"));
-//  ASSERT_EQ(elementContainer2->size(), 1);
-//  ASSERT_EQ(prop2->getCategory(), std::string("testCategory"));
-};
-
diff --git a/sdks/c++/basys.sdk.cc/tests/regression/submodel/api/parts/test_ConceptDescription.cpp b/sdks/c++/basys.sdk.cc/tests/regression/submodel/api/parts/test_ConceptDescription.cpp
index 8b2546e..f3b2400 100644
--- a/sdks/c++/basys.sdk.cc/tests/regression/submodel/api/parts/test_ConceptDescription.cpp
+++ b/sdks/c++/basys.sdk.cc/tests/regression/submodel/api/parts/test_ConceptDescription.cpp
@@ -8,61 +8,61 @@
 
 using namespace basyx::submodel;
 
-using ImplTypes = ::testing::Types
-<
-  std::tuple<map::ConceptDescription, map::Reference, map::DataSpecification>,
-  std::tuple<simple::ConceptDescription, simple::Reference, simple::DataSpecification>
->;
+using ImplTypes = ::testing::Types<
+    std::tuple<map::ConceptDescription, map::Reference, map::DataSpecification>,
+    std::tuple<simple::ConceptDescription, simple::Reference, simple::DataSpecification>>;
 
-template<class Impl>
-class ConceptDescriptionTest :public ::testing::Test {
+template <class Impl>
+class ConceptDescriptionTest : public ::testing::Test {
 protected:
-  using impl_t = typename std::tuple_element<0, Impl>::type;
-  using impl_ref_t = typename std::tuple_element<1, Impl>::type;
-  using impl_dataSpec_t = typename std::tuple_element<2, Impl>::type;
+    using impl_t = typename std::tuple_element<0, Impl>::type;
+    using impl_ref_t = typename std::tuple_element<1, Impl>::type;
+    using impl_dataSpec_t = typename std::tuple_element<2, Impl>::type;
 
-  std::unique_ptr<impl_t> conceptDescription;
-  std::unique_ptr<impl_ref_t> testingReference;
-  std::unique_ptr<impl_dataSpec_t> testingDataSpecification;
+    std::unique_ptr<impl_t> conceptDescription;
+    std::unique_ptr<impl_ref_t> testingReference;
+    std::unique_ptr<impl_dataSpec_t> testingDataSpecification;
+
 protected:
-	void SetUp() override
-	{
-	  simple::Identifier id;
-    conceptDescription = util::make_unique<impl_t>("test id", id);
-    simple::Key key(KeyElements::Property, true, KeyType::IdShort, "test");
-    testingReference = util::make_unique<impl_ref_t>(key);
-    testingDataSpecification = util::make_unique<impl_dataSpec_t>("test data spec", id);
-	}
+    void SetUp() override
+    {
+        simple::Identifier id;
+        conceptDescription = util::make_unique<impl_t>("test id", id);
+        simple::Key key(KeyElements::Property, true, KeyType::IdShort, "test");
+        testingReference = util::make_unique<impl_ref_t>(key);
+        testingDataSpecification = util::make_unique<impl_dataSpec_t>("test data spec", id);
+    }
 
-	void TearDown() override
-	{	}
+    void TearDown() override
+    {
+    }
 };
 
 TYPED_TEST_CASE(ConceptDescriptionTest, ImplTypes);
 
 TYPED_TEST(ConceptDescriptionTest, TestConstructor)
 {
-  auto & cases = this->conceptDescription->getIsCaseOf();
-  auto & references = this->conceptDescription->getDataSpecificationReference();
+    auto& cases = this->conceptDescription->getIsCaseOf();
+    auto& references = this->conceptDescription->getDataSpecificationReference();
 
-  ASSERT_EQ(references.size(), 0);
-  ASSERT_EQ(cases.size(), 0);
+    ASSERT_EQ(references.size(), 0);
+    ASSERT_EQ(cases.size(), 0);
 }
 
 TYPED_TEST(ConceptDescriptionTest, TestAddIsCaseOf)
 {
-  this->conceptDescription->addIsCaseOf(std::move(this->testingReference));
+    this->conceptDescription->addIsCaseOf(std::move(this->testingReference));
 
-  auto & references = this->conceptDescription->getIsCaseOf();
-  auto keys = references.at(0)->getKeys();
-  ASSERT_EQ(1, keys.size());
-  ASSERT_EQ("test", keys.at(0).getValue());
+    auto& references = this->conceptDescription->getIsCaseOf();
+    auto keys = references.at(0)->getKeys();
+    ASSERT_EQ(1, keys.size());
+    ASSERT_EQ("test", keys.at(0).getValue());
 }
 
 TYPED_TEST(ConceptDescriptionTest, TestAddEmbeddedDataSpecification)
 {
-  this->conceptDescription->addEmbeddedDataSpecification(std::move(this->testingDataSpecification));
+    this->conceptDescription->addEmbeddedDataSpecification(std::move(this->testingDataSpecification));
 
-  auto & references = this->conceptDescription->getEmbeddedDataSpecification();
-  ASSERT_NE(references.getElement("test data spec"), nullptr);
-}
\ No newline at end of file
+    auto& references = this->conceptDescription->getEmbeddedDataSpecification();
+    ASSERT_NE(references.getElement("test data spec"), nullptr);
+}
diff --git a/sdks/c++/basys.sdk.cc/tests/regression/submodel/api/parts/test_View.cpp b/sdks/c++/basys.sdk.cc/tests/regression/submodel/api/parts/test_View.cpp
index 0bdaf15..14f0c67 100644
--- a/sdks/c++/basys.sdk.cc/tests/regression/submodel/api/parts/test_View.cpp
+++ b/sdks/c++/basys.sdk.cc/tests/regression/submodel/api/parts/test_View.cpp
@@ -25,12 +25,12 @@
 protected:
 	void SetUp() override
 	{
-	  view = util::make_unique<impl_t>("TestView");
-    referable = util::make_unique<impl_ref_t>("TestReferable");
+	    view = util::make_unique<impl_t>("TestView");
+        referable = util::make_unique<impl_ref_t>("TestReferable");
 	}
 
 	void TearDown() override
-	{	}
+	{}
 };
 
 TYPED_TEST_CASE(ViewTest, ImplTypes);
diff --git a/sdks/c++/basys.sdk.cc/tests/regression/submodel/api/property/test_Property.cpp b/sdks/c++/basys.sdk.cc/tests/regression/submodel/api/property/test_Property.cpp
new file mode 100644
index 0000000..34a7353
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/tests/regression/submodel/api/property/test_Property.cpp
@@ -0,0 +1,315 @@
+#include <gtest/gtest.h>
+#include <BaSyx/submodel/simple/submodelelement/property/Property.h>
+#include <BaSyx/submodel/map_v2/submodelelement/property/Property.h>
+#include <BaSyx/submodel/simple/common/xsd_types/AnyURI.h>
+
+using namespace basyx::submodel;
+
+// Implementations to run tests for
+using ImplTypes = ::testing::Types<
+	simple::Property<int>,
+	map::Property<int>
+>;
+
+template<class Impl>
+class PropertyTest :public ::testing::Test {
+protected:
+	using impl_t = Impl;
+protected:
+	std::unique_ptr<api::IProperty> property;
+protected:
+	void SetUp() override
+	{
+		std::string idShort("id test");
+		this->property = util::make_unique<Impl>(idShort);
+	}
+
+	void TearDown() override
+	{
+	}
+};
+
+TYPED_TEST_CASE(PropertyTest, ImplTypes);
+
+TYPED_TEST(PropertyTest, TestConstructor)
+{
+  ASSERT_EQ(this->property->getIdShort(), std::string("id test"));
+}
+
+TYPED_TEST(PropertyTest, TestValueType)
+{
+  this->property->setValueType("valueType test");
+  ASSERT_EQ(this->property->getValueType(), std::string("valueType test"));
+}
+
+TYPED_TEST(PropertyTest, TestObject)
+{
+  basyx::object o(123);
+  this->property->setObject(o);
+  ASSERT_EQ(this->property->getObject(), basyx::object(123));
+}
+
+TYPED_TEST(PropertyTest, TestValueID)
+{
+  simple::Key key(KeyElements::ConceptDictionary, false, KeyType::Custom, "test key");
+  std::unique_ptr<api::IReference> ref = util::make_unique<simple::Reference>(key);
+  this->property->setValueId(*ref);
+  ASSERT_EQ(this->property->getValueId()->getKeys().at(0), key);
+}
+
+TYPED_TEST(PropertyTest, TestGetKeyElementType)
+{
+  ASSERT_EQ(this->property->getKeyElementType(), KeyElements::Property);
+}
+
+TYPED_TEST(PropertyTest, TestAnyURI)
+{
+  map::Property<simple::AnyURI> map_uri_prop("id");
+  ASSERT_EQ(map_uri_prop.getValueType(), std::string("anyURI"));
+}
+
+TYPED_TEST(PropertyTest, TestSafeDateTime)
+{
+  map::Property<simple::DateTime> dateTime_property("test id");
+  std::string valueType = dateTime_property.getValueType();
+  ASSERT_EQ(valueType, std::string("dateTime"));
+
+  //Try to add a DateTime
+  time_t t = 1563002200;
+  tm time = *gmtime(&t);
+  simple::DateTime test_time(time);
+  dateTime_property.setValue(test_time);
+
+  auto dateTime_string = dateTime_property.getMap().getProperty(map::PropertyPath::Value).GetStringContent();
+  ASSERT_EQ(dateTime_string, std::string("2019-07-13T07:16:40Z"));
+  tm saved_time = dateTime_property.getValue().getTime();
+  ASSERT_EQ(mktime(&saved_time), mktime(&time));
+}
+
+TYPED_TEST(PropertyTest, TestSafeDate)
+{
+  map::Property<simple::Date> date_property("test id");
+  std::string valueType = date_property.getValueType();
+  ASSERT_EQ(valueType, std::string("date"));
+
+  //Try to add a Date
+  tm date;
+  //epoche starts at 1900
+  date.tm_year = 1986 - 1900;
+  //month count starts at 0
+  date.tm_mon = 5 - 1;
+  date.tm_mday = 6;
+  simple::Date test_date(date);
+  date_property.setValue(test_date);
+
+  auto dateTime_string = date_property.getMap().getProperty(map::PropertyPath::Value).GetStringContent();
+  ASSERT_EQ(dateTime_string, std::string("1986-05-06Z"));
+  tm saved_date = date_property.getValue().getDate();
+  ASSERT_EQ(saved_date.tm_year, date.tm_year);
+  ASSERT_EQ(saved_date.tm_mon, date.tm_mon);
+  ASSERT_EQ(saved_date.tm_mday, date.tm_mday);
+}
+
+TYPED_TEST(PropertyTest, TestSafeDayTimeDuration)
+{
+  map::Property<simple::DayTimeDuration> duration_property("test id");
+  ASSERT_EQ(duration_property.getValueType(), std::string("dayTimeDuration"));
+
+  std::vector<std::pair<long, std::string>> test_cases = {
+      {0, "P"},
+      {12312123, "P142D12H2M3S"},
+      {12268923, "P142D2M3S"},
+      {12312120, "P142D12H2M"},
+      {59, "P59S"},
+      {60, "P1M"},
+      {-1, "-P1S"},
+      {-12312123, "-P142D12H2M3S"}
+  };
+
+  for (auto pair : test_cases)
+  {
+    std::chrono::duration<long> test_duration{pair.first};
+    simple::DayTimeDuration duration{test_duration};
+    duration_property.setValue(duration);
+
+    auto dateTime_string = duration_property.getMap().getProperty(map::PropertyPath::Value).GetStringContent();
+    ASSERT_EQ(dateTime_string, std::string(pair.second));
+    ASSERT_EQ(duration_property.getValue().getDuration().count(), test_duration.count());
+  }
+}
+
+
+
+TYPED_TEST(PropertyTest, TestSafeYearMonthDuration)
+{
+  map::Property<simple::YearMonthDuration> duration_property("test id");
+  ASSERT_EQ(duration_property.getValueType(), std::string("yearMonthDuration"));
+
+  std::vector<std::tuple<int, int, int, int, std::string>> test_cases = {
+      {0, 0, 0, 0, "P"},
+      {99, 0, 99, 0, "P99Y"},
+      {0, 11, 0, 11, "P11M"},
+      {50, 100, 58, 4, "P58Y4M"},
+      {50, -100, 41, 8, "P41Y8M"},
+      {-50, 100, -42, 4, "-P42Y4M"}
+  };
+
+  for (auto tuple : test_cases)
+  {
+    simple::YearMonthDuration duration{std::get<0>(tuple), std::get<1>(tuple)};
+    duration_property.setValue(duration);
+
+    auto duration_string = duration_property.getMap().getProperty(map::PropertyPath::Value).GetStringContent();
+    ASSERT_EQ(duration_string, std::string(std::get<4>(tuple)));
+    ASSERT_EQ(duration_property.getValue().getYears(), std::get<2>(tuple));
+    ASSERT_EQ(duration_property.getValue().getMonths(), std::get<3>(tuple));
+  }
+}
+
+TYPED_TEST(PropertyTest, TestTime)
+{
+  map::Property<simple::Time> time_property("test id");
+  ASSERT_EQ(time_property.getValueType(), std::string("time"));
+
+  std::vector<std::tuple<uint8_t, uint8_t, float, std::string, std::string>> test_cases = {
+      {0, 0, 0, "Z", "00:00:00Z"},
+      {11, 12, 3, "+01:00", "11:12:03+01:00"},
+      {12, 34, 56.789, "-12:00", "12:34:56.789-12:00"},
+      {1, 2, 3.04, "Z", "01:02:03.04Z"}
+  };
+
+  for (auto tuple : test_cases)
+  {
+    simple::Time time{std::get<0>(tuple), std::get<1>(tuple), std::get<2>(tuple), std::get<3>(tuple)};
+    time_property.setValue(time);
+
+    auto xsd_str = time_property.getMap().getProperty(map::PropertyPath::Value).GetStringContent();
+    ASSERT_EQ(xsd_str, std::string(std::get<4>(tuple)));
+    ASSERT_EQ(time_property.getValue().getHours(), std::get<0>(tuple));
+    ASSERT_EQ(time_property.getValue().getMinutes(), std::get<1>(tuple));
+    ASSERT_EQ(time_property.getValue().getSeconds(), std::get<2>(tuple));
+    ASSERT_EQ(std::string{time_property.getValue().getTimezone()}, std::string(std::get<3>(tuple)));
+  }
+}
+
+TYPED_TEST(PropertyTest, TestGregorianYearMonth)
+{
+  map::Property<simple::GYearMonth> gregorianYearMonth_property("test id");
+  ASSERT_EQ(gregorianYearMonth_property.getValueType(), std::string("gYearMonth"));
+
+  std::vector<std::tuple<int, uint8_t, std::string, std::string>> test_cases = {
+      {0, 01, "Z", "0000-01Z"},
+      {11, 12, "+01:00", "0011-12+01:00"},
+      {2016, 1, "-12:00", "2016-01-12:00"},
+      {-1, 10, "Z", "-0001-10Z"},
+      {20202, 10, "Z", "20202-10Z"}
+  };
+
+  for (auto tuple : test_cases)
+  {
+    simple::GYearMonth yearMonth{std::get<0>(tuple), std::get<1>(tuple), std::get<2>(tuple)};
+    gregorianYearMonth_property.setValue(yearMonth);
+
+    auto xsd_str = gregorianYearMonth_property.getMap().getProperty(map::PropertyPath::Value).GetStringContent();
+    ASSERT_EQ(xsd_str, std::string(std::get<3>(tuple)));
+    ASSERT_EQ(gregorianYearMonth_property.getValue().getYear(), std::get<0>(tuple));
+    ASSERT_EQ(gregorianYearMonth_property.getValue().getMonth(), std::get<1>(tuple));
+    ASSERT_EQ(std::string{gregorianYearMonth_property.getValue().getTimezone()}, std::string(std::get<2>(tuple)));
+  }
+}
+
+TYPED_TEST(PropertyTest, TestGregorianYear)
+{
+  map::Property<simple::GYear> gregorianYear_property("test id");
+  ASSERT_EQ(gregorianYear_property.getValueType(), std::string("gYear"));
+
+  std::vector<std::tuple<int, std::string, std::string>> test_cases = {
+      {0, "Z", "0000Z"},
+      {11, "+01:00", "0011+01:00"},
+      {2016, "-12:00", "2016-12:00"},
+      {-1, "Z", "-0001Z"},
+      {-15445, "Z", "-15445Z"},
+      {20202, "Z", "20202Z"}
+  };
+
+  for (auto tuple : test_cases)
+  {
+    simple::GYear year{std::get<0>(tuple), std::get<1>(tuple)};
+    gregorianYear_property.setValue(year);
+
+    auto xsd_str = gregorianYear_property.getMap().getProperty(map::PropertyPath::Value).GetStringContent();
+    ASSERT_EQ(xsd_str, std::string(std::get<2>(tuple)));
+    ASSERT_EQ(gregorianYear_property.getValue().getYear(), std::get<0>(tuple));
+    ASSERT_EQ(std::string{gregorianYear_property.getValue().getTimezone()}, std::string(std::get<1>(tuple)));
+  }
+}
+
+TYPED_TEST(PropertyTest, TestGregorianMonthDay)
+{
+  map::Property<simple::GMonthDay> gregorianMonthDay_property("test id");
+  ASSERT_EQ(gregorianMonthDay_property.getValueType(), std::string("gMonthDay"));
+
+  std::vector<std::tuple<uint8_t, uint8_t, std::string, std::string, uint8_t, uint8_t>> test_cases = {
+      {1, 1, "Z", "--01-01Z", 1, 1},
+      {10, 31, "+01:00", "--10-31+01:00", 10, 31},
+      {13, 32,  "-12:00", "--01-31-12:00", 1, 31},
+  };
+
+  for (auto tuple : test_cases)
+  {
+    simple::GMonthDay monthDay{std::get<0>(tuple), std::get<1>(tuple), std::get<2>(tuple)};
+    gregorianMonthDay_property.setValue(monthDay);
+
+    auto xsd_str = gregorianMonthDay_property.getMap().getProperty(map::PropertyPath::Value).GetStringContent();
+    ASSERT_EQ(xsd_str, std::string(std::get<3>(tuple)));
+    ASSERT_EQ(gregorianMonthDay_property.getValue().getMonth(), std::get<4>(tuple));
+    ASSERT_EQ(gregorianMonthDay_property.getValue().getDay(), std::get<5>(tuple));
+    ASSERT_EQ(std::string{gregorianMonthDay_property.getValue().getTimezone()}, std::string(std::get<2>(tuple)));
+  }
+}
+
+TYPED_TEST(PropertyTest, TestGregorianDay)
+{
+  map::Property<simple::GDay> gregorianDay_property("test id");
+  ASSERT_EQ(gregorianDay_property.getValueType(), std::string("gDay"));
+
+  std::vector<std::tuple<uint8_t, std::string, std::string, uint8_t>> test_cases = {
+      {1, "Z", "---01Z", 1},
+      {10, "+01:00", "---10+01:00", 10},
+      {32,  "-12:00", "---01-12:00", 1},
+  };
+
+  for (auto tuple : test_cases)
+  {
+    simple::GDay day{std::get<0>(tuple), std::get<1>(tuple)};
+    gregorianDay_property.setValue(day);
+
+    auto xsd_str = gregorianDay_property.getMap().getProperty(map::PropertyPath::Value).GetStringContent();
+    ASSERT_EQ(xsd_str, std::string(std::get<2>(tuple)));
+    ASSERT_EQ(gregorianDay_property.getValue().getDay(), std::get<3>(tuple));
+    ASSERT_EQ(std::string{gregorianDay_property.getValue().getTimezone()}, std::string(std::get<1>(tuple)));
+  }
+}
+
+TYPED_TEST(PropertyTest, TestGregorianMonth)
+{
+  map::Property<simple::GMonth> gregorianMonth_property("test id");
+  ASSERT_EQ(gregorianMonth_property.getValueType(), std::string("gMonth"));
+
+  std::vector<std::tuple<uint8_t, std::string, std::string, uint8_t>> test_cases = {
+      {1, "Z", "--01Z", 1},
+      {10, "+01:00", "--10+01:00", 10},
+      {13,  "-12:00", "--01-12:00", 1},
+  };
+
+  for (auto tuple : test_cases)
+  {
+    simple::GMonth month{std::get<0>(tuple), std::get<1>(tuple)};
+    gregorianMonth_property.setValue(month);
+
+    auto xsd_str = gregorianMonth_property.getMap().getProperty(map::PropertyPath::Value).GetStringContent();
+    ASSERT_EQ(xsd_str, std::string(std::get<2>(tuple)));
+    ASSERT_EQ(gregorianMonth_property.getValue().getMonth(), std::get<3>(tuple));
+    ASSERT_EQ(std::string{gregorianMonth_property.getValue().getTimezone()}, std::string(std::get<1>(tuple)));
+  }
+}
diff --git a/sdks/c++/basys.sdk.cc/tests/regression/submodel/api/qualifier/test_AdministrativeInformation.cpp b/sdks/c++/basys.sdk.cc/tests/regression/submodel/api/qualifier/test_AdministrativeInformation.cpp
new file mode 100644
index 0000000..9603475
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/tests/regression/submodel/api/qualifier/test_AdministrativeInformation.cpp
@@ -0,0 +1,81 @@
+#include <gtest/gtest.h>
+#include <BaSyx/submodel/simple/qualifier/AdministrativeInformation.h>
+#include <BaSyx/submodel/map_v2/qualifier/AdministrativeInformation.h>
+
+using namespace basyx::submodel;
+
+// Implementations to run tests for
+using ImplTypes = ::testing::Types<
+	simple::AdministrativeInformation,
+	map::AdministrativeInformation
+>;
+
+template<class Impl>
+class AdministrativeInformationTest :public ::testing::Test {
+protected:
+	using impl_t = Impl;
+protected:
+	std::unique_ptr<api::IAdministrativeInformation> administrativeInformation;
+  std::unique_ptr<api::IAdministrativeInformation> administrativeInformationMembersSet;
+protected:
+	void SetUp() override
+	{
+		this->administrativeInformation = util::make_unique<Impl>();
+    this->administrativeInformationMembersSet = util::make_unique<Impl>("TestVersion", "TestRevision");
+	}
+
+	void TearDown() override
+	{
+	}
+};
+
+TYPED_TEST_CASE(AdministrativeInformationTest, ImplTypes);
+
+TYPED_TEST(AdministrativeInformationTest, TestConstructor)
+{
+  ASSERT_EQ(this->administrativeInformation->getRevision(), nullptr);
+  ASSERT_EQ(this->administrativeInformation->getVersion(), nullptr);
+}
+
+TYPED_TEST(AdministrativeInformationTest, TestStringConstructor)
+{
+  ASSERT_EQ(*this->administrativeInformationMembersSet->getVersion(), "TestVersion");
+  ASSERT_EQ(*this->administrativeInformationMembersSet->getRevision(), "TestRevision");
+}
+
+TYPED_TEST(AdministrativeInformationTest, TestSetVersion)
+{
+  ASSERT_EQ(this->administrativeInformation->getVersion(), nullptr);
+
+  this->administrativeInformation->setVersion("TestVersion");
+
+  ASSERT_EQ(*this->administrativeInformation->getVersion(), "TestVersion");
+}
+
+TYPED_TEST(AdministrativeInformationTest, TestSetRevision)
+{
+  ASSERT_EQ(this->administrativeInformation->getRevision(), nullptr);
+
+  this->administrativeInformation->setRevision("TestRevision");
+
+  ASSERT_EQ(*this->administrativeInformation->getRevision(), "TestRevision");
+}
+
+TYPED_TEST(AdministrativeInformationTest, TestHasVersion)
+{
+  ASSERT_FALSE(this->administrativeInformation->hasVersion());
+
+  this->administrativeInformation->setVersion("TestVersion");
+
+  ASSERT_TRUE(this->administrativeInformation->hasVersion());
+}
+
+TYPED_TEST(AdministrativeInformationTest, TestHasRevision)
+{
+  ASSERT_FALSE(this->administrativeInformation->hasRevision());
+
+  this->administrativeInformation->setRevision("TestRevision");
+
+  ASSERT_TRUE(this->administrativeInformation->hasRevision());
+}
+
diff --git a/sdks/c++/basys.sdk.cc/tests/regression/submodel/api/qualifier/test_Identifiable.cpp b/sdks/c++/basys.sdk.cc/tests/regression/submodel/api/qualifier/test_Identifiable.cpp
index 4af3c94..520544c 100644
--- a/sdks/c++/basys.sdk.cc/tests/regression/submodel/api/qualifier/test_Identifiable.cpp
+++ b/sdks/c++/basys.sdk.cc/tests/regression/submodel/api/qualifier/test_Identifiable.cpp
@@ -11,18 +11,25 @@
 
 // Implementations to run tests for
 using ImplTypes = ::testing::Types<
-	simple::Identifiable,
-	map::Identifiable
+  std::tuple<simple::Identifiable, simple::AdministrativeInformation>,
+  std::tuple<map::Identifiable, map::AdministrativeInformation>
 >;
 
 template<class Impl>
 class IdentifiableTest :public ::testing::Test {
 protected:
-	std::unique_ptr<api::IIdentifiable> identifiable;
+  using impl_t = typename std::tuple_element<0, Impl>::type;
+  using impl_admin_info_t = typename std::tuple_element<1, Impl>::type;
+
+	std::unique_ptr<impl_t> identifiable;
+
+	impl_admin_info_t administrative_information;
+
 protected:
 	void SetUp() override
 	{
-		this->identifiable = util::make_unique<Impl>(idShort, simple::Identifier{ IdentifierType::Custom, "Test" });
+		this->identifiable = util::make_unique<impl_t>(idShort, simple::Identifier{ IdentifierType::Custom, "Test" });
+		this->administrative_information = impl_admin_info_t("test version", "test revision");
 	}
 
 	void TearDown() override
@@ -41,4 +48,14 @@
 	auto ident = this->identifiable->getIdentification();
 	ASSERT_EQ(ident.getId(), "Test" );
 	ASSERT_EQ(ident.getIdType(), IdentifierType::Custom );
+}
+
+TYPED_TEST(IdentifiableTest, TestSetAdministrativeInformation)
+{
+  ASSERT_FALSE(this->identifiable->hasAdministrativeInformation());
+
+  this->identifiable->setAdministrativeInformation(this->administrative_information);
+
+  ASSERT_TRUE(this->identifiable->hasAdministrativeInformation());
+  ASSERT_EQ(*this->identifiable->getAdministrativeInformation().getVersion(), std::string("test version"));
 }
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/tests/regression/submodel/api/test_Submodel.cpp b/sdks/c++/basys.sdk.cc/tests/regression/submodel/api/test_Submodel.cpp
new file mode 100644
index 0000000..b8b428f
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/tests/regression/submodel/api/test_Submodel.cpp
@@ -0,0 +1,88 @@
+#include <gtest/gtest.h>
+
+#include <BaSyx/submodel/map_v2/SubModel.h>
+#include <BaSyx/submodel/map_v2/aas/Asset.h>
+#include <BaSyx/submodel/map_v2/aas/AssetAdministrationShell.h>
+#include <BaSyx/submodel/simple/SubModel.h>
+#include <BaSyx/submodel/simple/aas/Asset.h>
+#include <BaSyx/submodel/simple/aas/AssetAdministrationShell.h>
+
+using namespace basyx::submodel;
+using namespace basyx::submodel::map;
+using namespace basyx::submodel::simple;
+
+// Implementations to run tests for
+struct map_types {
+	using submodel_t = map::SubModel;
+	using asset_t = map::Asset;
+	using aas_t = map::AssetAdministrationShell;
+};
+
+struct simple_types {
+	using submodel_t = simple::SubModel;
+	using asset_t = simple::Asset;
+	using aas_t = simple::AssetAdministrationShell;
+};
+
+using TestTypes = ::testing::Types<
+	map_types,
+	simple_types>;
+
+template <class Types>
+class SubmodelTest : public ::testing::Test {
+public:
+	using types = Types;
+
+protected:
+	std::unique_ptr<typename Types::submodel_t> subModel;
+
+protected:
+	void SetUp() override
+	{
+	}
+
+	void TearDown() override
+	{
+	}
+};
+
+TYPED_TEST_CASE(SubmodelTest, TestTypes);
+
+TYPED_TEST(SubmodelTest, TestSubmodelConstructor)
+{
+	using namespace basyx::submodel;
+
+
+	typename TypeParam::submodel_t submodel{ "test", { simple::Identifier { IdentifierType::Custom, "test" } } };
+};
+
+TYPED_TEST(SubmodelTest, TestSubmodelReferences)
+{
+	using aas_t = typename TypeParam::aas_t;
+	using asset_t = typename TypeParam::asset_t;
+	using submodel_t = typename TypeParam::submodel_t;
+
+	// Create asset
+	asset_t asset{
+		"asset", /* idShort */
+		simple::Identifier::Custom("asset") /* identifier */
+	};
+
+	// Create the asset administration shell and assign asset
+	aas_t aas{
+		"aas", /* idShort */
+		simple::Identifier::Custom("aas"), /* identifier */
+		asset
+	};
+
+
+	auto & submodels = aas.getSubmodels();
+	submodels.template createElement<submodel_t>("submodel", simple::Identifier::Custom("submodel"));
+
+	ASSERT_EQ(submodels.size(), 1);
+
+	auto sm = submodels.getElement("submodel");
+	ASSERT_TRUE(sm != nullptr);
+
+	ASSERT_EQ(sm->getIdShort(), "submodel");
+}
diff --git a/sdks/c++/basys.sdk.cc/tests/regression/submodel/map/common/test_ElementContainer.cpp b/sdks/c++/basys.sdk.cc/tests/regression/submodel/map/common/test_ElementContainer.cpp
deleted file mode 100644
index c139467..0000000
--- a/sdks/c++/basys.sdk.cc/tests/regression/submodel/map/common/test_ElementContainer.cpp
+++ /dev/null
@@ -1,69 +0,0 @@
-#include <gtest/gtest.h>
-
-#include <BaSyx/submodel/map_v2/common/ElementContainer.h>
-#include <BaSyx/submodel/map_v2/submodelelement/SubmodelElement.h>
-#include <BaSyx/submodel/map_v2/submodelelement/property/Property.h>
-
-using namespace basyx::submodel;
-using namespace basyx::submodel::map;
-using namespace basyx::submodel::api;
-
-class ElementContainerTest : public ::testing::Test {
-protected:
-	ElementContainer<ISubmodelElement> elementContainer;
-protected:
-	void SetUp() override
-	{
-	}
-
-	void TearDown() override
-	{
-	}
-};
-
-TEST_F(ElementContainerTest, TestInit)
-{
-	ASSERT_EQ(this->elementContainer.size(), 0);
-}
-
-
-TEST_F(ElementContainerTest, TestAdd)
-{
-	auto prop = util::make_unique<Property<int>>( "testProperty" );
-	prop->setValue(5);
-
-	this->elementContainer.addElement(std::move(prop));
-	ASSERT_EQ(this->elementContainer.size(), 1);
-
-	auto submodelElement = this->elementContainer.getElement("testProperty");
-	auto propB = dynamic_cast<map::Property<int>*>(submodelElement);
-	ASSERT_NE(propB, nullptr);
-	ASSERT_EQ(propB->getValue(), 5);
-};
-
-TEST_F(ElementContainerTest, TestCreate)
-{
-	auto prop = this->elementContainer.createElement<Property<int>>("testProperty");
-	ASSERT_EQ(this->elementContainer.size(), 1);
-	prop->setValue(5);
-
-	auto submodelElement = this->elementContainer.getElement("testProperty");
-	auto propB = dynamic_cast<map::Property<int>*>(submodelElement);
-	ASSERT_NE(propB, nullptr);
-	ASSERT_EQ(propB->getValue(), 5);
-};
-
-TEST_F(ElementContainerTest, TestCreateDeleteAfterwards)
-{
-	auto prop = this->elementContainer.createElement<Property<int>>("testProperty");
-	ASSERT_EQ(this->elementContainer.size(), 1);
-	prop->setValue(5);
-
-	// Delete in map
-	auto & objectList = this->elementContainer.getMap().Get<basyx::object::object_list_t&>();
-	objectList.clear();
-	ASSERT_EQ(this->elementContainer.size(), 0);
-	auto prop_b = this->elementContainer.getElement("testProperty");
-	ASSERT_EQ(prop_b, nullptr);
-};
-
diff --git a/sdks/c++/basys.sdk.cc/tests/regression/submodel/map_v2/common/test_ElementContainer.cpp b/sdks/c++/basys.sdk.cc/tests/regression/submodel/map_v2/common/test_ElementContainer.cpp
new file mode 100644
index 0000000..d3fdf6c
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/tests/regression/submodel/map_v2/common/test_ElementContainer.cpp
@@ -0,0 +1,42 @@
+#include <gtest/gtest.h>
+
+#include <BaSyx/submodel/map_v2/common/ElementContainer.h>
+#include <BaSyx/submodel/map_v2/submodelelement/SubmodelElement.h>
+#include <BaSyx/submodel/map_v2/submodelelement/property/Property.h>
+
+using namespace basyx::submodel;
+using namespace basyx::submodel::map;
+using namespace basyx::submodel::api;
+
+class ElementContainerTest : public ::testing::Test {
+protected:
+	ElementContainer<ISubmodelElement> elementContainer;
+protected:
+	void SetUp() override
+	{
+	}
+
+	void TearDown() override
+	{
+	}
+};
+
+TEST_F(ElementContainerTest, TestInit)
+{
+	ASSERT_EQ(this->elementContainer.size(), 0);
+}
+
+
+TEST_F(ElementContainerTest, TestCreateDeleteAfterwards)
+{
+	auto prop = this->elementContainer.createElement<Property<int>>("testProperty");
+	ASSERT_EQ(this->elementContainer.size(), 1);
+	prop->setValue(5);
+
+	// Delete in map
+	auto && objectMap = this->elementContainer.getMap();
+	objectMap.removeProperty("testProperty");
+	ASSERT_EQ(this->elementContainer.size(), 0);
+	auto prop_b = this->elementContainer.getElement("testProperty");
+	ASSERT_EQ(prop_b, nullptr);
+};
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/tests/regression/vab/provider/basyx/test_BaSyxNative.cpp b/sdks/c++/basys.sdk.cc/tests/regression/vab/provider/basyx/test_BaSyxNative.cpp
index 6d7c82d..36f6a8d 100644
--- a/sdks/c++/basys.sdk.cc/tests/regression/vab/provider/basyx/test_BaSyxNative.cpp
+++ b/sdks/c++/basys.sdk.cc/tests/regression/vab/provider/basyx/test_BaSyxNative.cpp
@@ -9,6 +9,7 @@
 
 #include "snippet/MapRead.h"
 #include "snippet/MapCreateDelete.h"
+#include "snippet/MapUpdate.h"
 #include "snippet/MapInvoke.h"
 #include "snippet/TestCollectionProperty.h"
 
@@ -113,6 +114,14 @@
 	tests::regression::vab::snippet::MapRead::test(&provider);
 }
 
+TEST_F(TestBaSyxNative, MapUpdate)
+{
+	auto connector = util::make_unique<vab::connector::native::NativeConnector>("127.0.0.1", port);
+	auto provider = ConnectedModelProvider(connector.get());
+
+	tests::regression::vab::snippet::MapUpdate::test(&provider);
+}
+
 TEST_F(TestBaSyxNative, MapCreateDelete)
 {
 	auto connector = util::make_unique<vab::connector::native::NativeConnector>("127.0.0.1", port);
diff --git a/sdks/c++/basys.sdk.cc/tests/regression/vab/provider/test_hashmap.cpp b/sdks/c++/basys.sdk.cc/tests/regression/vab/provider/test_hashmap.cpp
index 2fa04fe..e2da424 100644
--- a/sdks/c++/basys.sdk.cc/tests/regression/vab/provider/test_hashmap.cpp
+++ b/sdks/c++/basys.sdk.cc/tests/regression/vab/provider/test_hashmap.cpp
@@ -13,6 +13,7 @@
 
 #include "snippet/MapRead.h"
 #include "snippet/MapCreateDelete.h"
+#include "snippet/MapUpdate.h"
 #include "snippet/MapInvoke.h"
 #include "snippet/TestCollectionProperty.h"
 
@@ -188,6 +189,13 @@
 	tests::regression::vab::snippet::MapRead::test(&hashMapProvider);
 }
 
+TEST_F(TestBaSyxHashmapProvider, MapUpdate)
+{
+	vab::provider::VABModelProvider hashMapProvider{ tests::support::make_simple_vab_element() };
+
+	tests::regression::vab::snippet::MapUpdate::test(&hashMapProvider);
+}
+
 TEST_F(TestBaSyxHashmapProvider, MapCreateDelete)
 {
 	vab::provider::VABModelProvider hashMapProvider{ tests::support::make_simple_vab_element() };
diff --git a/sdks/c++/basys.sdk.cc/tests/regression/vab/snippet/MapCreateDelete.h b/sdks/c++/basys.sdk.cc/tests/regression/vab/snippet/MapCreateDelete.h
index 79b6628..83d16cb 100644
--- a/sdks/c++/basys.sdk.cc/tests/regression/vab/snippet/MapCreateDelete.h
+++ b/sdks/c++/basys.sdk.cc/tests/regression/vab/snippet/MapCreateDelete.h
@@ -76,7 +76,8 @@
 	{
 		// Delete at Root
 		// - by basyx::object - should not work, root is a map
-		modelProvider->deleteValue("inRoot", 1.2);
+		auto deleteResult = modelProvider->deleteValue("inRoot", 1.2);
+		ASSERT_EQ(deleteResult, basyx::object::error::MalformedRequest);
 		basyx::object toTest = modelProvider->getModelPropertyValue("inRoot");
 		ASSERT_ANY_EQ(toTest, 1.2);
 		// - by index
@@ -91,6 +92,10 @@
 		toTest = modelProvider->getModelPropertyValue("inroot");
 		ASSERT_TRUE(toTest.IsNull());
 
+		// Delete empty path
+		auto deleteError = modelProvider->deleteValue("", "");
+		ASSERT_EQ(deleteError, basyx::object::error::MalformedRequest);
+
 		// Delete at Map
 		// - by basyx::object - should not work in maps, because basyx::object refers to a contained basyx::object, not the index
 		modelProvider->deleteValue("/structure/map/", "inMap");
diff --git a/sdks/c++/basys.sdk.cc/tests/regression/vab/snippet/MapUpdate.h b/sdks/c++/basys.sdk.cc/tests/regression/vab/snippet/MapUpdate.h
index 94b4302..703d892 100644
--- a/sdks/c++/basys.sdk.cc/tests/regression/vab/snippet/MapUpdate.h
+++ b/sdks/c++/basys.sdk.cc/tests/regression/vab/snippet/MapUpdate.h
@@ -50,9 +50,16 @@
 
 		auto createError = modelProvider->createValue("unkown/newElement", 5);
 		ASSERT_EQ(createError, basyx::object::error::PropertyNotFound);
-	
-		auto createError2 = modelProvider->createValue("newElement", 10);
-		ASSERT_EQ(createError, basyx::object::error::PropertyNotFound);
+		auto createError2 = modelProvider->getModelPropertyValue("unknown/newElement");
+		ASSERT_TRUE(createError2.IsError());
+		ASSERT_EQ(createError2.getError(), basyx::object::error::PropertyNotFound);
+
+
+		auto updateError = modelProvider->setModelPropertyValue("newElement", 10);
+		ASSERT_EQ(updateError, basyx::object::error::PropertyNotFound);
+		auto updateError2 = modelProvider->getModelPropertyValue("newElement");
+		ASSERT_TRUE(updateError2.IsError());
+		ASSERT_EQ(updateError2.getError(), basyx::object::error::PropertyNotFound);
 
 		// Test updating an existing null-element
 		modelProvider->setModelPropertyValue("special/null", true);
@@ -68,9 +75,10 @@
 		auto newMap = basyx::object::make_map();
 		newMap.insertKey("testKey", "testValue");
 		auto error = modelProvider->setModelPropertyValue("", newMap);
-		ASSERT_EQ(error, basyx::object::error::PropertyNotFound);
-		ASSERT_TRUE(modelProvider->getModelPropertyValue("testKey").IsError());
-		ASSERT_TRUE(modelProvider->getModelPropertyValue("primitives/integer").IsError());
+		//ASSERT_EQ(error, basyx::object::error::ObjectAlreadyExists);
+		//ASSERT_TRUE(modelProvider->getModelPropertyValue("testKey").IsError());
+		//ASSERT_EQ(modelProvider->getModelPropertyValue("testKey").getError(), basyx::object::error::PropertyNotFound);
+//		ASSERT_TRUE(modelProvider->getModelPropertyValue("primitives/integer").IsError());
 	};
 };
 
diff --git a/sdks/c++/basys.sdk.cc/tests/regression/vab/snippet/TestCollectionProperty.h b/sdks/c++/basys.sdk.cc/tests/regression/vab/snippet/TestCollectionProperty.h
index 382e338..ba4e0a4 100644
--- a/sdks/c++/basys.sdk.cc/tests/regression/vab/snippet/TestCollectionProperty.h
+++ b/sdks/c++/basys.sdk.cc/tests/regression/vab/snippet/TestCollectionProperty.h
@@ -35,6 +35,11 @@
     	ASSERT_TRUE(collection.InstanceOf<basyx::object::list_t<int>>());
     	ASSERT_EQ(collection.Get<basyx::object::list_t<int>&>().size(), 2);
 
+		// Test invalid list access - single list elements cannot be accessed directly
+		auto singleAccess = modelProvider->getModelPropertyValue("/structure/list/0");
+		ASSERT_TRUE(singleAccess.IsError());
+		ASSERT_EQ(singleAccess.getError(), basyx::object::error::PropertyNotFound);
+
 		// Test invalid list access
 		auto invalid = modelProvider->getModelPropertyValue("/structure/list/invalid");
 		ASSERT_TRUE(invalid.IsNull());
diff --git a/sdks/c++/basys.sdk.cc/tests/regression/vab/support/MockupModelProvider.h b/sdks/c++/basys.sdk.cc/tests/regression/vab/support/MockupModelProvider.h
index f2170ce..734cfeb 100644
--- a/sdks/c++/basys.sdk.cc/tests/regression/vab/support/MockupModelProvider.h
+++ b/sdks/c++/basys.sdk.cc/tests/regression/vab/support/MockupModelProvider.h
@@ -14,99 +14,101 @@
 
 using namespace basyx;
 
-class MockupModelProvider: public vab::core::IModelProvider {
+class MockupModelProvider : public vab::core::IModelProvider {
 
 public:
-	enum class CalledFunction {
-		NONE, GET, SET, CREATE, DELETE_SIMPLE, DELETE_COMPLEX, INVOKE
-	};
+    enum class CalledFunction {
+        NONE,
+        GET,
+        SET,
+        CREATE,
+        DELETE_SIMPLE,
+        DELETE_COMPLEX,
+        INVOKE
+    };
 
-	CalledFunction called;
+    CalledFunction called;
 
-	std::string path;
-	basyx::object val;
-	basyx::object clock;
+    std::string path;
+    basyx::object val;
+    basyx::object clock;
 
-	MockupModelProvider()
-		: called{CalledFunction::NONE}
-		, clock{0}
-	{
-	}
-	
-	virtual ~MockupModelProvider() 
-	{}
+    MockupModelProvider()
+        : called { CalledFunction::NONE }
+        , clock { 0 }
+    {
+    }
 
-	virtual basyx::object getModelPropertyValue(const std::string & path) override {
-		// Return dummy clock
-		if (path.find("clock") != std::string::npos)
-		{
-			return clock;
-		}
-		// Ignore frozen
-		else if ( path.find("frozen") != std::string::npos) 
-		{
-			val = basyx::object{ nullptr };
-		}
-		else
-		{
-			called = CalledFunction::GET;
-			this->path = path;
-			val = basyx::object{ 2 };
-		};
+    virtual ~MockupModelProvider()
+    {
+    }
 
-		return val;
-	}
+    virtual basyx::object getModelPropertyValue(const std::string& path) override
+    {
+        // Return dummy clock
+        if (path.find("clock") != std::string::npos) {
+            return clock;
+        }
+        // Ignore frozen
+        else if (path.find("frozen") != std::string::npos) {
+            val = basyx::object { nullptr };
+        } else {
+            called = CalledFunction::GET;
+            this->path = path;
+            val = basyx::object { 2 };
+        };
 
-	virtual basyx::object::error setModelPropertyValue(const std::string & path, const basyx::object newValue) override
-	{
-		// Set dummy clock
-		if (path.find("clock") != std::string::npos)
-		{
-			clock = std::move(newValue);
-		}
-		else // ignore frozen
-		if (path.find("frozen") == std::string::npos) {
-			called = CalledFunction::SET;
-			this->path = path;
-			this->val = std::move(newValue);
-		}
+        return val;
+    }
 
-		return basyx::object::error::None;
-	}
+    virtual basyx::object::error setModelPropertyValue(const std::string& path, const basyx::object newValue) override
+    {
+        // Set dummy clock
+        if (path.find("clock") != std::string::npos) {
+            clock = std::move(newValue);
+        } else // ignore frozen
+            if (path.find("frozen") == std::string::npos) {
+            called = CalledFunction::SET;
+            this->path = path;
+            this->val = std::move(newValue);
+        }
 
-	/**
+        return basyx::object::error::None;
+    }
+
+    /**
 	 * Create/insert a value in a collection
 	 */
-	virtual basyx::object::error createValue(const std::string & path, const basyx::object addedValue) override
-	{
-		called = CalledFunction::CREATE;
-		this->path = path;
-		this->val = std::move(addedValue);
-		return basyx::object::error::None;
-	}
+    virtual basyx::object::error createValue(const std::string& path, const basyx::object addedValue) override
+    {
+        called = CalledFunction::CREATE;
+        this->path = path;
+        this->val = std::move(addedValue);
+        return basyx::object::error::None;
+    }
 
-	virtual basyx::object::error deleteValue(const std::string & path, const basyx::object deletedValue) override 
-	{
-		called = CalledFunction::DELETE_COMPLEX;
-		this->path = path;
-		this->val = std::move(deletedValue);
-		return basyx::object::error::None;
-	}
-	
-	virtual basyx::object::error deleteValue(const std::string & path)
-	{
-		called = CalledFunction::DELETE_SIMPLE;
-		this->path = path;
-		return basyx::object::error::None;
-	}
+    virtual basyx::object::error deleteValue(const std::string& path, const basyx::object deletedValue) override
+    {
+        called = CalledFunction::DELETE_COMPLEX;
+        this->path = path;
+        this->val = std::move(deletedValue);
+        return basyx::object::error::None;
+    }
 
-	virtual basyx::object invokeOperation(const std::string & path, basyx::object parameter) override
-	{
-		called = CalledFunction::INVOKE;
-		this->path = path;
-		this->val = std::move(parameter);
-		return basyx::object{ 3 };
-	};
+    virtual basyx::object::error deleteValue(const std::string& path) override
+    {
+        called = CalledFunction::DELETE_SIMPLE;
+        this->path = path;
+        return basyx::object::error::None;
+    }
+
+    virtual basyx::object invokeOperation(const std::string& path, basyx::object parameter) override
+    {
+        called = CalledFunction::INVOKE;
+        this->path = path;
+        this->val = std::move(parameter);
+        return basyx::object { 3 };
+    };
 };
 
 #endif /* REGRESSION_TESTS_BACKENDS_PROTOCOLS_BASYX_MOCKUPMODELPROVIDER_H_ */
diff --git a/sdks/java/basys.sdk/pom.xml b/sdks/java/basys.sdk/pom.xml
index 534a2a9..f02c306 100644
--- a/sdks/java/basys.sdk/pom.xml
+++ b/sdks/java/basys.sdk/pom.xml
@@ -5,7 +5,7 @@
 
 	<groupId>org.eclipse.basyx</groupId>
 	<artifactId>basyx.sdk</artifactId>
-	<version>0.0.1-SNAPSHOT</version>
+	<version>1.0.0</version>
 	<name>BaSyx SDK</name>
 
 	<packaging>jar</packaging>
@@ -14,6 +14,19 @@
 		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
 		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
 	</properties>
+	
+	<repositories>
+		<!--  Additional repository for MQTT Client releases (Paho Java Client) -->
+	    <repository>
+	        <id>Eclipse Paho Repo</id>
+	        <url>https://repo.eclipse.org/content/repositories/paho-releases/</url>
+	    </repository>
+	    <!-- Additional repository for MQTT Broker releases (Moquette Java Broker) -->
+	    <repository>
+    		<id>bintray</id>
+    		<url>https://jcenter.bintray.com</url>
+  		</repository>
+	</repositories>
 
 	<build>
 		<sourceDirectory>src/main/java</sourceDirectory>
@@ -111,6 +124,20 @@
 			<version>4.12</version>
 			<scope>test</scope>
 		</dependency>
+		
+		<!-- Moquette MQTT broker for testing MQTT events -->
+		<dependency>
+			<groupId>io.moquette</groupId>
+			<artifactId>moquette-broker</artifactId>
+			<version>0.12.1</version>
+			<scope>test</scope>
+		    <exclusions>
+				<exclusion> 
+					<groupId>org.slf4j</groupId>
+					<artifactId>slf4j-log4j12</artifactId>
+				</exclusion>
+		    </exclusions>
+		</dependency>
 
 		<!-- Eclipse Milo (for OPC-UA client) -->
 		<dependency>
@@ -144,23 +171,30 @@
 		<dependency>
 			<groupId>org.glassfish.jersey.core</groupId>
 			<artifactId>jersey-client</artifactId>
-			<version>2.29</version>
+			<version>2.30</version>
 		</dependency>
 
 		<!-- Jersey InjectionManager (for Jersey client)  -->
 		<dependency>
 			<groupId>org.glassfish.jersey.inject</groupId>
 			<artifactId>jersey-hk2</artifactId>
-			<version>2.29</version>
+			<version>2.30.1</version>
 		</dependency>
 
 		<!-- Tomcat 8 for HTTP server resource -->
 		<dependency>
 			<groupId>org.apache.tomcat</groupId>
 			<artifactId>tomcat-catalina</artifactId>
-			<version>8.0.53</version>
+			<version>8.5.41</version>
 		</dependency>
-		
+
+		<!-- Used for creating .aasx files -->
+		<dependency>
+			<groupId>org.apache.poi</groupId>
+			<artifactId>poi-ooxml</artifactId>
+			<version>4.1.2</version>
+		</dependency>
+
 		<!-- Logger -->
 		<dependency>
     		<groupId>ch.qos.logback</groupId>
@@ -174,5 +208,21 @@
     		<artifactId>janino</artifactId>
     		<version>2.7.5</version>
 		</dependency>
+		
+		<!-- Paho Java Client for MQTT -->
+		<dependency>
+			<groupId>org.eclipse.paho</groupId>
+			<artifactId>org.eclipse.paho.client.mqttv3</artifactId>
+			<version>1.2.5</version>
+		</dependency>
+		
+		<!-- JSON Serialization -->
+		<dependency>
+			<groupId>com.google.code.gson</groupId>
+			<artifactId>gson</artifactId>
+			<version>2.8.5</version>
+		</dependency>
+		
 	</dependencies>
-</project>
\ No newline at end of file
+</project>
+
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/aggregator/AASAggregator.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/aggregator/AASAggregator.java
index f2adccb..c3f7810 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/aggregator/AASAggregator.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/aggregator/AASAggregator.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.aas.aggregator;
 
 import java.util.Collection;
@@ -8,10 +17,19 @@
 import org.eclipse.basyx.aas.aggregator.api.IAASAggregator;
 import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
 import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
 import org.eclipse.basyx.aas.restapi.AASModelProvider;
-import org.eclipse.basyx.aas.restapi.VABMultiSubmodelProvider;
+import org.eclipse.basyx.aas.restapi.MultiSubmodelProvider;
+import org.eclipse.basyx.aas.restapi.api.IAASAPI;
+import org.eclipse.basyx.aas.restapi.api.IAASAPIFactory;
+import org.eclipse.basyx.aas.restapi.vab.VABAASAPIFactory;
 import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.submodel.restapi.api.ISubmodelAPIFactory;
+import org.eclipse.basyx.submodel.restapi.vab.VABSubmodelAPIFactory;
 import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
+import org.eclipse.basyx.vab.protocol.api.IConnectorFactory;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorFactory;
 
 /**
  * An implementation of the IAASAggregator interface using maps internally
@@ -21,14 +39,65 @@
  */
 public class AASAggregator implements IAASAggregator {
 
-	protected Map<String, VABMultiSubmodelProvider> aasProviderMap = new HashMap<>();
+	protected Map<String, MultiSubmodelProvider> aasProviderMap = new HashMap<>();
+
+	protected IAASRegistry registry;
+
+	/**
+	 * Store AAS API Provider. By default, uses the VAB API Provider
+	 */
+	protected IAASAPIFactory aasApiProvider;
+
+	/**
+	 * Store Submodel API Provider. By default, uses the VAB Submodel Provider
+	 */
+	protected ISubmodelAPIFactory smApiProvider;
+
+	/**
+	 * Constructs default AAS Aggregator
+	 */
+	public AASAggregator() {
+		this.aasApiProvider = new VABAASAPIFactory();
+		this.smApiProvider = new VABSubmodelAPIFactory();
+	}
+
+	/**
+	 * Constructs an AAS aggregator with custom API providers
+	 */
+	public AASAggregator(IAASAPIFactory aasApiProvider, ISubmodelAPIFactory smApiProvider) {
+		this.aasApiProvider = aasApiProvider;
+		this.smApiProvider = smApiProvider;
+	}
+
+	/**
+	 * Constructs AAS Aggregator using the passed registry. This registry is used to
+	 * resolve requests for remote submodels
+	 * 
+	 * @param registry
+	 */
+	public AASAggregator(IAASRegistry registry) {
+		this.registry = registry;
+		this.aasApiProvider = new VABAASAPIFactory();
+		this.smApiProvider = new VABSubmodelAPIFactory();
+	}
+
+	/**
+	 * Constructs AAS Aggregator using the passed registry. This registry is used to
+	 * resolve requests for remote submodels. Additionally takes custom API providers;
+	 */
+	public AASAggregator(IAASAPIFactory aasApiProvider, ISubmodelAPIFactory smApiProvider,
+			IAASRegistry registry) {
+		this.registry = registry;
+		this.aasApiProvider = aasApiProvider;
+		this.smApiProvider = smApiProvider;
+	}
 
 	@SuppressWarnings("unchecked")
 	@Override
 	public Collection<IAssetAdministrationShell> getAASList() {
 		return aasProviderMap.values().stream().map(p -> {
 			try {
-				return p.getModelPropertyValue("/aas");
+				return p.getValue("/aas");
 			} catch (Exception e1) {
 				e1.printStackTrace();
 				throw new RuntimeException();
@@ -43,14 +112,10 @@
 	@SuppressWarnings("unchecked")
 	@Override
 	public IAssetAdministrationShell getAAS(IIdentifier aasId) {
-		VABMultiSubmodelProvider provider = aasProviderMap.get(aasId.getId());
-
-		if (provider == null) {
-			throw new ResourceNotFoundException("AAS with Id " + aasId.getId() + " does not exist");
-		}
+		IModelProvider aasProvider = getAASProvider(aasId);
 
 		// get all Elements from provider
-		Map<String, Object> aasMap = (Map<String, Object>) provider.getModelPropertyValue("/aas");
+		Map<String, Object> aasMap = (Map<String, Object>) aasProvider.getValue("/aas");
 		IAssetAdministrationShell aas = AssetAdministrationShell.createAsFacade(aasMap);
 
 		return aas;
@@ -58,12 +123,21 @@
 
 	@Override
 	public void createAAS(AssetAdministrationShell aas) {
-		aasProviderMap.put(aas.getIdentification().getId(), new VABMultiSubmodelProvider(new AASModelProvider(aas)));
+		aasProviderMap.put(aas.getIdentification().getId(), createMultiSubmodelProvider(aas));
 	}
 
 	@Override
 	public void updateAAS(AssetAdministrationShell aas) {
-		aasProviderMap.put(aas.getIdentification().getId(), new VABMultiSubmodelProvider(new AASModelProvider(aas)));
+		aasProviderMap.put(aas.getIdentification().getId(), createMultiSubmodelProvider(aas));
+	}
+
+	private MultiSubmodelProvider createMultiSubmodelProvider(AssetAdministrationShell aas) {
+		IConnectorFactory connProvider = new HTTPConnectorFactory();
+		IAASAPI aasApi = aasApiProvider.getAASApi(aas);
+		AASModelProvider contentProvider = new AASModelProvider(aasApi);
+		MultiSubmodelProvider multiAASProvider = new MultiSubmodelProvider(contentProvider, registry,
+				connProvider, smApiProvider, aasApiProvider);
+		return multiAASProvider;
 	}
 
 	@Override
@@ -71,7 +145,14 @@
 		aasProviderMap.remove(aasId.getId());
 	}
 
-	public VABMultiSubmodelProvider getProviderForAASId(String aasId) {
-		return aasProviderMap.get(aasId);
+	@Override
+	public IModelProvider getAASProvider(IIdentifier aasId) {
+		MultiSubmodelProvider provider = aasProviderMap.get(aasId.getId());
+
+		if (provider == null) {
+			throw new ResourceNotFoundException("AAS with Id " + aasId.getId() + " does not exist");
+		}
+
+		return provider;
 	}
-}
\ No newline at end of file
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/aggregator/api/IAASAggregator.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/aggregator/api/IAASAggregator.java
index 98cba3f..2a10375 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/aggregator/api/IAASAggregator.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/aggregator/api/IAASAggregator.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.aas.aggregator.api;
 
 import java.util.Collection;
@@ -5,6 +14,8 @@
 import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
 import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
 import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
 
 
 /**
@@ -29,9 +40,17 @@
 	 * @param aasId the ID of the AAS
 	 * @return the requested AAS
 	 */
-	public IAssetAdministrationShell getAAS(IIdentifier aasId);
+	public IAssetAdministrationShell getAAS(IIdentifier aasId) throws ResourceNotFoundException;
 	
 	/**
+	 * Retrieves the provider for a specific Asset Administration Shell
+	 * 
+	 * @param aasId the ID of the AAS
+	 * @return the requested AAS provider
+	 */
+	public IModelProvider getAASProvider(IIdentifier aasId) throws ResourceNotFoundException;
+
+	/**
 	 * Creates a new Asset Administration Shell at the endpoint
 	 * 
 	 * @param aas the AAS to be created
@@ -43,7 +62,7 @@
 	 * 
 	 * @param aas the updated AAS
 	 */
-	public void updateAAS(AssetAdministrationShell aas);
+	public void updateAAS(AssetAdministrationShell aas) throws ResourceNotFoundException;
 	
 	/**
 	 * Deletes a specific Asset Administration Shell
@@ -52,4 +71,4 @@
 	 */
 	public void deleteAAS(IIdentifier aasId);
 
-}
\ No newline at end of file
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/aggregator/proxy/AASAggregatorProxy.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/aggregator/proxy/AASAggregatorProxy.java
index 98e8e45..c3fc9a7 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/aggregator/proxy/AASAggregatorProxy.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/aggregator/proxy/AASAggregatorProxy.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.aas.aggregator.proxy;
 
 import java.util.Collection;
@@ -5,12 +14,15 @@
 import java.util.stream.Collectors;
 
 import org.eclipse.basyx.aas.aggregator.api.IAASAggregator;
+import org.eclipse.basyx.aas.aggregator.restapi.AASAggregatorProvider;
 import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.connected.ConnectedAssetAdministrationShell;
 import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
 import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
 import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
 import org.eclipse.basyx.vab.coder.json.connector.JSONConnector;
 import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+import org.eclipse.basyx.vab.modelprovider.VABPathTools;
 import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
 import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnector;
 import org.slf4j.Logger;
@@ -27,7 +39,7 @@
 	 *            The endpoint of the aggregator with a HTTP-REST interface
 	 */
 	public AASAggregatorProxy(String aasAggregatorURL) {
-		this(new JSONConnector(new HTTPConnector(aasAggregatorURL)));
+		this(new JSONConnector(new HTTPConnector(harmonizeURL(aasAggregatorURL))));
 	}
 
 	/**
@@ -37,40 +49,78 @@
 	 * @param provider
 	 */
 	public AASAggregatorProxy(IModelProvider provider) {
-		this.provider = new VABElementProxy("/aasList", provider);
+		this.provider = new VABElementProxy("", provider);
+	}
+
+	/**
+	 * Adds the "/shells" suffix if it does not exist
+	 * 
+	 * @param url
+	 * @return
+	 */
+	private static String harmonizeURL(String url) {
+		return VABPathTools.harmonizePathWithSuffix(url, AASAggregatorProvider.PREFIX);
 	}
 
 	@SuppressWarnings("unchecked")
 	@Override
 	public Collection<IAssetAdministrationShell> getAASList() {
-		Collection<Map<String, Object>> collection = (Collection<Map<String, Object>>) provider.getModelPropertyValue("");
+		Collection<Map<String, Object>> collection = (Collection<Map<String, Object>>) provider.getValue("");
 		logger.debug("Getting all AAS");
-		return collection.stream().map(m -> AssetAdministrationShell.createAsFacade(m)).collect(Collectors.toSet());
+		return collection.stream().map(m -> AssetAdministrationShell.createAsFacade(m)).map(aas -> getConnectedAAS(aas.getIdentification(), aas)).collect(Collectors.toList());
 	}
 
-	@SuppressWarnings("unchecked")
 	@Override
 	public IAssetAdministrationShell getAAS(IIdentifier aasId) {
 		logger.debug("Getting AAS with id " + aasId);
-		return AssetAdministrationShell.createAsFacade((Map<String, Object>) provider.getModelPropertyValue(aasId.getId()));
+		return getConnectedAAS(aasId);
+	}
+
+	@SuppressWarnings("unchecked")
+	private ConnectedAssetAdministrationShell getConnectedAAS(IIdentifier aasId) {
+		VABElementProxy proxy = getAASProxy(aasId);
+		Map<String, Object> map = (Map<String, Object>) proxy.getValue("");
+		AssetAdministrationShell aas = AssetAdministrationShell.createAsFacade(map);
+		return new ConnectedAssetAdministrationShell(proxy, aas);
+	}
+
+	private ConnectedAssetAdministrationShell getConnectedAAS(IIdentifier aasId, AssetAdministrationShell localCopy) {
+		VABElementProxy proxy = getAASProxy(aasId);
+		return new ConnectedAssetAdministrationShell(proxy, localCopy);
+	}
+
+
+	private VABElementProxy getAASProxy(IIdentifier aasId) {
+		String path = VABPathTools.concatenatePaths(getEncodedIdentifier(aasId), "aas");
+		VABElementProxy proxy = new VABElementProxy(path, provider);
+		return proxy;
 	}
 
 	@Override
 	public void createAAS(AssetAdministrationShell aas) {
-		provider.createValue("", aas);
+		provider.setValue(getEncodedIdentifier(aas.getIdentification()), aas);
 		logger.info("AAS with Id " + aas.getIdentification().getId() + " created");
 	}
 
 	@Override
 	public void updateAAS(AssetAdministrationShell aas) {
-		provider.setModelPropertyValue(aas.getIdentification().getId(), aas);
+		provider.setValue(getEncodedIdentifier(aas.getIdentification()), aas);
 		logger.info("AAS with Id " + aas.getIdentification().getId() + " updated");
 	}
 
 	@Override
 	public void deleteAAS(IIdentifier aasId) {
-		provider.deleteValue(aasId.getId());
-		logger.info("AAS with Id " + aasId.getId() + " created");
+		provider.deleteValue(getEncodedIdentifier(aasId));
+		logger.info("AAS with Id " + aasId.getId() + " deleted");
+	}
+
+	@Override
+	public IModelProvider getAASProvider(IIdentifier aasId) {
+		return new VABElementProxy(getEncodedIdentifier(aasId), provider);
+	}
+
+	private String getEncodedIdentifier(IIdentifier aasId) {
+		return VABPathTools.encodePathElement(aasId.getId());
 	}
 
 }
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/aggregator/restapi/AASAggregatorProvider.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/aggregator/restapi/AASAggregatorProvider.java
index 420bb54..e4fc3a1 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/aggregator/restapi/AASAggregatorProvider.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/aggregator/restapi/AASAggregatorProvider.java
@@ -1,18 +1,26 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.aas.aggregator.restapi;
 
-import java.io.UnsupportedEncodingException;
-import java.net.URLDecoder;
 import java.util.Map;
 
-import org.eclipse.basyx.aas.aggregator.AASAggregator;
+import org.eclipse.basyx.aas.aggregator.api.IAASAggregator;
 import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
 import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
 import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
 import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
 import org.eclipse.basyx.submodel.metamodel.map.modeltype.ModelType;
 import org.eclipse.basyx.vab.exception.provider.MalformedRequestException;
 import org.eclipse.basyx.vab.exception.provider.ProviderException;
-import org.eclipse.basyx.vab.exception.provider.ResourceAlreadyExistsException;
 import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
 import org.eclipse.basyx.vab.modelprovider.VABPathTools;
 import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
@@ -24,112 +32,114 @@
  *
  */
 public class AASAggregatorProvider implements IModelProvider {
-	
-	private AASAggregator aggregator;
-	
-	private static final String PREFIX = "aasList";
-	private static final String ENCODING_SCHEME = "UTF-8";
-	
-	public AASAggregatorProvider(AASAggregator aggregator) {
+
+	private IAASAggregator aggregator;
+
+	public static final String PREFIX = "shells";
+
+	public AASAggregatorProvider(IAASAggregator aggregator) {
 		this.aggregator = aggregator;
 	}
 
 	/**
 	 * Check for correctness of path and returns a stripped path (i.e. no leading
 	 * prefix)
+	 * 
 	 * @param path
 	 * @return
-	 * @throws MalformedRequestException 
+	 * @throws MalformedRequestException
 	 */
 	private String stripPrefix(String path) throws MalformedRequestException {
 		path = VABPathTools.stripSlashes(path);
 		if (!path.startsWith(PREFIX)) {
 			throw new MalformedRequestException("Path " + path + " not recognized as aggregator path. Has to start with " + PREFIX);
 		}
-		path = path.replace(PREFIX, "");
+		path = path.replaceFirst(PREFIX, "");
 		path = VABPathTools.stripSlashes(path);
 		return path;
 	}
-	
+
 	/**
 	 * Makes sure, that given Object is an AAS by checking its ModelType<br />
 	 * Creates a new AAS with the content of the given Map
 	 * 
-	 * @param value the AAS Map object
+	 * @param value
+	 *            the AAS Map object
 	 * @return an AAS
-	 * @throws MalformedRequestException 
+	 * @throws MalformedRequestException
 	 */
 	@SuppressWarnings("unchecked")
 	private AssetAdministrationShell createAASFromMap(Object value) throws MalformedRequestException {
-		
-		//check if the given value is a Map
-		if(!(value instanceof Map)) {
+
+		// check if the given value is a Map
+		if (!(value instanceof Map)) {
 			throw new MalformedRequestException("Given newValue is not a Map");
 		}
 
 		Map<String, Object> map = (Map<String, Object>) value;
-		
-		//check if the given Map contains an AAS
+
+		// check if the given Map contains an AAS
 		String type = ModelType.createAsFacade(map).getName();
-		
-		//have to accept Objects without modeltype information,
-		//as modeltype is not part of the public metamodel
-		if(!AssetAdministrationShell.MODELTYPE.equals(type) && type != null) {
+
+		// have to accept Objects without modeltype information,
+		// as modeltype is not part of the public metamodel
+		if (!AssetAdministrationShell.MODELTYPE.equals(type) && type != null) {
 			throw new MalformedRequestException("Given newValue map has not the correct ModelType");
 		}
-		
+
 		AssetAdministrationShell aas = AssetAdministrationShell.createAsFacade(map);
-		
+
 		return aas;
 	}
-	
-	
-	
+
 	@Override
-	public Object getModelPropertyValue(String path) throws ProviderException {
+	public Object getValue(String path) throws ProviderException {
 		path = stripPrefix(path);
-		
-		if(path.isEmpty()) { //Return all AAS if path is empty
+
+		if (path.isEmpty()) { // Return all AAS if path is empty
 			return aggregator.getAASList();
 		} else {
 			String[] splitted = VABPathTools.splitPath(path);
 			if (splitted.length == 1) { // A specific AAS was requested
-				String id = decodePath(splitted[0]);
+				String id = VABPathTools.decodePathElement(splitted[0]);
 				IAssetAdministrationShell aas = aggregator.getAAS(new ModelUrn(id));
 				return aas;
 			} else {
-				String id = decodePath(splitted[0]);
+				String id = VABPathTools.decodePathElement(splitted[0]);
 				String restPath = VABPathTools.skipEntries(path, 1);
-				return aggregator.getProviderForAASId(id).getModelPropertyValue(restPath);
+				IIdentifier identifier = new Identifier(IdentifierType.CUSTOM, id);
+				return aggregator.getAASProvider(identifier).getValue(restPath);
 			}
 		}
 	}
 
 	@Override
-	public void setModelPropertyValue(String path, Object newValue) throws ProviderException {
+	public void setValue(String path, Object newValue) throws ProviderException {
 		path = stripPrefix(path);
-		
+
 		if (!path.isEmpty()) { // Overwriting existing entry
 			if (!path.contains("/")) { // Update of AAS
 
 				AssetAdministrationShell aas = createAASFromMap(newValue);
 				// Decode encoded path
-				path = decodePath(path);
+				path = VABPathTools.decodePathElement(path);
 				ModelUrn identifier = new ModelUrn(path);
 
 				if (!aas.getIdentification().getId().equals(path)) {
 					throw new MalformedRequestException("Given aasID and given AAS do not match");
 				}
 
-				if (aggregator.getAAS(identifier) == null) {
-					throw new ResourceAlreadyExistsException("Can not update non existing value '" + path + "'. Try create instead.");
+				try {
+					aggregator.getAAS(identifier);
+					aggregator.updateAAS(aas);
+				} catch (ResourceNotFoundException e) {
+					aggregator.createAAS(aas);
 				}
-
-				aggregator.updateAAS(aas);
 			} else { // Update of contained element
-				String id = decodePath(VABPathTools.getEntry(path, 0));
+				String id = VABPathTools.decodePathElement(VABPathTools.getEntry(path, 0));
 				String restPath = VABPathTools.skipEntries(path, 1);
-				aggregator.getProviderForAASId(id).setModelPropertyValue(restPath, newValue);
+				IIdentifier identifier = new Identifier(IdentifierType.CUSTOM, id);
+				aggregator.getAASProvider(identifier).setValue(restPath, newValue);
 			}
 		} else {
 			throw new MalformedRequestException("Set with empty path is not supported by aggregator");
@@ -139,22 +149,16 @@
 	@Override
 	public void createValue(String path, Object newEntity) throws ProviderException {
 		path = stripPrefix(path);
-		
-		if (path.isEmpty()) { // Creating new entry
-			AssetAdministrationShell aas = createAASFromMap(newEntity);
-			try {
-				aggregator.getAAS(aas.getIdentification());
-				throw new ResourceAlreadyExistsException("AAS with path (id) " + path + " exists already. Try update instead");
-			} catch (ResourceNotFoundException e) {
-				aggregator.createAAS(aas);
-			}
-			
+
+		if (path.isEmpty()) {
+			throw new MalformedRequestException("Create with empty path is not supported by aggregator");
 		} else {
-			String id = decodePath(VABPathTools.getEntry(path, 0));
+			String id = VABPathTools.decodePathElement(VABPathTools.getEntry(path, 0));
 			String restPath = VABPathTools.skipEntries(path, 1);
-			aggregator.getProviderForAASId(id).createValue(restPath, newEntity);
+			IIdentifier identifier = new Identifier(IdentifierType.CUSTOM, id);
+			aggregator.getAASProvider(identifier).createValue(restPath, newEntity);
 		}
-		
+
 	}
 
 	@Override
@@ -162,43 +166,26 @@
 		path = stripPrefix(path);
 
 		if (!path.isEmpty()) { // Deleting an entry
-			// Decode encoded path
-			path = decodePath(path);
-			
 			if (!path.contains("/")) {
-				IIdentifier identifier = new ModelUrn(path);
+				String aasId = VABPathTools.decodePathElement(path);
+				IIdentifier identifier = new ModelUrn(aasId);
 
 				if (aggregator.getAAS(identifier) == null) {
-					throw new ResourceNotFoundException("Value '" + path + "' to be deleted does not exists.");
+					throw new ResourceNotFoundException("Value '" + aasId + "' to be deleted does not exists.");
 				}
 
 				aggregator.deleteAAS(identifier);
 			} else {
-				String id = decodePath(VABPathTools.getEntry(path, 0));
+				String id = VABPathTools.decodePathElement(VABPathTools.getEntry(path, 0));
 				String restPath = VABPathTools.skipEntries(path, 1);
-				aggregator.getProviderForAASId(id).deleteValue(restPath);
+				IIdentifier identifier = new Identifier(IdentifierType.CUSTOM, id);
+				aggregator.getAASProvider(identifier).deleteValue(restPath);
 			}
 		} else {
 			throw new MalformedRequestException("Delete with empty path is not supported by registry");
 		}
 	}
 
-	/**
-	 * Decodes the given path using the default encoding scheme
-	 * 
-	 * @param path
-	 * @return
-	 */
-	private String decodePath(String path) {
-		try {
-			path = URLDecoder.decode(path, ENCODING_SCHEME);
-		} catch (UnsupportedEncodingException e) {
-			// This should never happen
-			throw new RuntimeException("Wrong encoding for " + path);
-		}
-		return path;
-	}
-
 	@Override
 	public void deleteValue(String path, Object obj) throws ProviderException {
 		throw new MalformedRequestException("DeleteValue with parameter not supported by aggregator");
@@ -207,10 +194,10 @@
 	@Override
 	public Object invokeOperation(String path, Object... parameter) throws ProviderException {
 		path = stripPrefix(path);
-		String id = decodePath(VABPathTools.getEntry(path, 0));
+		String id = VABPathTools.decodePathElement(VABPathTools.getEntry(path, 0));
 		String restPath = VABPathTools.skipEntries(path, 1);
-		return aggregator.getProviderForAASId(id).invokeOperation(restPath, parameter);
+		IIdentifier identifier = new Identifier(IdentifierType.CUSTOM, id);
+		return aggregator.getAASProvider(identifier).invokeOperation(restPath, parameter);
 	}
-	
 
 }
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/factory/aasx/AASXFactory.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/factory/aasx/AASXFactory.java
new file mode 100644
index 0000000..28cf3bb
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/factory/aasx/AASXFactory.java
@@ -0,0 +1,273 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.aas.factory.aasx;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.UUID;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.stream.StreamResult;
+
+import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
+import org.apache.poi.openxml4j.opc.OPCPackage;
+import org.apache.poi.openxml4j.opc.PackagePart;
+import org.apache.poi.openxml4j.opc.PackagePartName;
+import org.apache.poi.openxml4j.opc.PackagingURIHelper;
+import org.apache.poi.openxml4j.opc.RelationshipSource;
+import org.apache.poi.openxml4j.opc.TargetMode;
+import org.apache.poi.openxml4j.opc.internal.MemoryPackagePart;
+import org.eclipse.basyx.aas.factory.xml.MetamodelToXMLConverter;
+import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.api.parts.asset.IAsset;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.api.parts.IConceptDescription;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.File;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.eclipse.basyx.vab.modelprovider.VABPathTools;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * This class can be used to generate an .aasx file from
+ * Metamodel Objects and the Files referred to in the Submodels
+ * 
+ * @author conradi
+ *
+ */
+public class AASXFactory {
+	
+	private static Logger logger = LoggerFactory.getLogger(AASXFactory.class);
+	
+	private static final String MIME_PLAINTXT = "text/plain";
+	private static final String MIME_XML = "application/xml";
+
+	private static final String ORIGIN_RELTYPE = "http://www.admin-shell.io/aasx/relationships/aasx-origin";
+	private static final String ORIGIN_PATH = "/aasx/aasx-origin";
+	private static final String ORIGIN_CONTENT = "Intentionally empty.";
+	
+	
+	private static final String AASSPEC_RELTYPE = "http://www.admin-shell.io/aasx/relationships/aas-spec";
+	private static final String XML_PATH = "/aasx/xml/content.xml";
+	
+	
+	private static final String AASSUPPL_RELTYPE = "http://www.admin-shell.io/aasx/relationships/aas-suppl";
+	
+	
+	
+	/**
+	 * Generates the .aasx file and writes it to the given OutputStream
+	 * 
+	 * @param aasList the AASs to be saved in the .aasx
+	 * @param assetList the Assets to be saved in the .aasx
+	 * @param conceptDescriptionList the ConceptDescriptions to be saved in the .aasx
+	 * @param submodelList the Submodels to be saved in the .aasx
+	 * @param files the files referred to in the Submodels
+	 * @param os the OutputStream the resulting .aasx is written to
+	 * @throws IOException
+	 * @throws TransformerException
+	 * @throws ParserConfigurationException
+	 */
+	public static void buildAASX(Collection<IAssetAdministrationShell> aasList, Collection<IAsset> assetList, 
+			Collection<IConceptDescription> conceptDescriptionList, Collection<ISubmodel> submodelList, Collection<InMemoryFile> files, OutputStream os) throws IOException, TransformerException, ParserConfigurationException {
+		
+		prepareFilePaths(submodelList);
+		
+		OPCPackage rootPackage = OPCPackage.create(os);
+		
+		// Create the empty aasx-origin file
+		PackagePart origin = createAASXPart(rootPackage, rootPackage, ORIGIN_PATH, MIME_PLAINTXT, ORIGIN_RELTYPE, ORIGIN_CONTENT.getBytes());
+		
+		// Convert the given Metamodels to XML
+		String xml = convertToXML(aasList, assetList, conceptDescriptionList, submodelList);
+		
+		// Save the XML to aasx/xml/content.xml
+		PackagePart xmlPart = createAASXPart(rootPackage, origin, XML_PATH, MIME_XML, AASSPEC_RELTYPE, xml.getBytes());
+		
+		storeFilesInAASX(submodelList, files, rootPackage, xmlPart);
+		
+		saveAASX(os, rootPackage);
+	}
+
+	/**
+	 * Stores the files from the Submodels in the .aasx file
+	 * 
+	 * @param submodelList the Submodels
+	 * @param files the content of the files
+	 * @param rootPackage the OPCPackage
+	 * @param xmlPart the Part the files should be related to
+	 */
+	private static void storeFilesInAASX(Collection<ISubmodel> submodelList, Collection<InMemoryFile> files,
+			OPCPackage rootPackage, PackagePart xmlPart) {
+		
+		for(ISubmodel sm: submodelList) {
+			for(File file: findFileElements(sm.getSubmodelElements().values())) {
+				String filePath = file.getValue();
+				try {
+					InMemoryFile content = findFileByPath(files, filePath);
+					logger.trace("Writing file '" + filePath + "' to .aasx.");
+					createAASXPart(rootPackage, xmlPart, filePath, file.getMimeType(), AASSUPPL_RELTYPE, content.getFileContent());
+				} catch (ResourceNotFoundException e) {
+					// Log that a file is missing and continue building the .aasx
+					logger.warn("Could not add File '" + filePath + "'. It was not contained in given InMemoryFiles.");
+				}
+			}
+		}
+	}
+	
+	/**
+	 * Saves the OPCPackage to the given OutputStream
+	 * 
+	 * @param os the Stream to be saved to
+	 * @param rootPackage the Package to be saved
+	 * @throws IOException
+	 */
+	private static void saveAASX(OutputStream os, OPCPackage rootPackage) throws IOException {
+		rootPackage.flush();
+		rootPackage.save(os);
+	}
+	
+	/**
+	 * Generates a UUID. Every element of the 
+	 * .aasx needs a unique Id according to the specification
+	 * 
+	 * @return UUID
+	 */
+	private static String createUniqueID() {
+		return UUID.randomUUID().toString();
+	}
+	
+	/**
+	 * Creates a Part (a file in the .aasx) of the .aasx and adds it to the Package
+	 * 
+	 * @param root the OPCPackage
+	 * @param relateTo the Part of the OPC the relationship of the new Part should be added to
+	 * @param path the path inside the .aasx where the new Part should be created
+	 * @param mimeType the mime-type of the file
+	 * @param relType the type of the Relationship
+	 * @param content the data the new part should contain
+	 * @return the created PackagePart; Returned in case it is needed late as a Part to relate to
+	 */
+	private static PackagePart createAASXPart(OPCPackage root, RelationshipSource relateTo, String path, String mimeType, String relType, byte[] content) {
+		if(mimeType == null || mimeType.equals("")) {
+			throw new RuntimeException("Could not create AASX Part '" + path + "'. No MIME_TYPE specified.");
+		}
+		
+		PackagePartName partName = null;
+		MemoryPackagePart part = null;
+		try {
+			partName = PackagingURIHelper.createPartName(path);
+			part = new MemoryPackagePart(root, partName, mimeType);
+		} catch (InvalidFormatException e) {
+			// This occurs if the given MIME-Type is not valid according to RFC2046
+			throw new RuntimeException("Could not create AASX Part '" + path + "'", e);
+		}		
+		writeDataToPart(part, content);
+		root.registerPartAndContentType(part);
+		relateTo.addRelationship(partName, TargetMode.INTERNAL, relType, createUniqueID());
+		return part;
+	}
+	
+	/**
+	 * Writes the content of a byte[] to a Part
+	 * 
+	 * @param part the Part to be written to
+	 * @param content the content to be written to the part
+	 */
+	private static void writeDataToPart(PackagePart part, byte[] content) {
+		try(OutputStream ostream = part.getOutputStream();) {
+			ostream.write(content);
+			ostream.flush();
+		} catch (Exception e) {
+			throw new RuntimeException("Failed to write content to AASX Part '" + part.getPartName().getName() + "'", e);
+		}
+	}
+	
+	/**
+	 * Uses the MetamodelToXMLConverter to generate the XML
+	 */
+	private static String convertToXML(Collection<IAssetAdministrationShell> aasList, Collection<IAsset> assetList, 
+			Collection<IConceptDescription> conceptDescriptionList, Collection<ISubmodel> submodelList) throws TransformerException, ParserConfigurationException {
+		
+		StringWriter writer = new StringWriter();
+		MetamodelToXMLConverter.convertToXML(aasList, assetList, conceptDescriptionList, submodelList, new StreamResult(writer));
+		
+		return writer.toString();
+	}
+	
+	/**
+	 * Gets the File elements from a collection of elements
+	 * Also recursively searches in SubmodelElementCollections
+	 * 
+	 * @param elements the Elements to be searched for File elements
+	 * @return the found Files
+	 */
+	private static Collection<File> findFileElements(Collection<ISubmodelElement> elements) {		
+		Collection<File> files = new ArrayList<>();
+		
+		for(ISubmodelElement element: elements) {
+			if(element instanceof File) {
+				files.add((File) element);
+			} else if(element instanceof SubmodelElementCollection) {
+				// Recursive call to deal with SubmodelElementCollections
+				files.addAll(findFileElements(((SubmodelElementCollection) element).getSubmodelElements().values()));
+			}
+		}
+		
+		return files;
+	}
+	
+	/**
+	 * Replaces the path in all File Elements with the result of preparePath
+	 * 
+	 * @param submodels the Submodels
+	 */
+	private static void prepareFilePaths(Collection<ISubmodel> submodels) {
+		submodels.stream()
+			.forEach(sm -> findFileElements(sm.getSubmodelElements().values()).stream().forEach(f -> f.setValue(preparePath(f.getValue()))));
+	}
+	
+	/**
+	 * Removes the serverpart from a path and ensures it starts with a slash
+	 * 
+	 * @param path the path to be prepared
+	 * @return the prepared path
+	 */
+	private static String preparePath(String path) {
+		String newPath = VABPathTools.getPathFromURL(path);
+		if(!newPath.startsWith("/")) {
+			newPath = "/" + newPath;
+		}
+		return newPath;
+	}
+	
+	/**
+	 * Finds an InMemoryFile by its path
+	 * 
+	 * @param files the InMemoryFiles
+	 * @param path the path of the wanted file
+	 * @return the InMemoryFile if it was found; else null
+	 */
+	private static InMemoryFile findFileByPath(Collection<InMemoryFile> files, String path) {
+		for(InMemoryFile file: files) {
+			if(preparePath(file.getPath()).equals(path)) {
+				return file;
+			}
+		}
+		throw new ResourceNotFoundException("The wanted file '" + path + "' was not found in the given files.");
+	}
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/factory/aasx/InMemoryFile.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/factory/aasx/InMemoryFile.java
new file mode 100644
index 0000000..ec8385f
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/factory/aasx/InMemoryFile.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.aas.factory.aasx;
+
+/**
+ * Container class for the content of a File and its Path
+ * 
+ * @author conradi
+ *
+ */
+public class InMemoryFile {
+
+	private byte[] fileContent;
+	private String path;
+	
+	public InMemoryFile(byte[] fileContent, String path) {
+		this.fileContent = fileContent;
+		this.path = path;
+	}
+
+	public byte[] getFileContent() {
+		return fileContent;
+	}
+
+	public String getPath() {
+		return path;
+	}
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/factory/json/JSONToMetamodelConverter.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/factory/json/JSONToMetamodelConverter.java
new file mode 100644
index 0000000..634e67e
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/factory/json/JSONToMetamodelConverter.java
@@ -0,0 +1,113 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.aas.factory.json;
+
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.map.parts.Asset;
+import org.eclipse.basyx.submodel.metamodel.api.reference.IKey;
+import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.parts.ConceptDescription;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
+import org.eclipse.basyx.vab.coder.json.serialization.DefaultTypeFactory;
+import org.eclipse.basyx.vab.coder.json.serialization.GSONTools;
+
+/**
+ * This class can be used to parse JSON to Metamodel Objects
+ * 
+ * @author conradi
+ *
+ */
+public class JSONToMetamodelConverter {
+	
+	private Map<String, Object> root;
+	
+	// Buffer used for parsed assets to prevent deserializing them multiple times
+	private List<Asset> assetBuf;
+
+	@SuppressWarnings("unchecked")
+	public JSONToMetamodelConverter(String jsonContent) {
+		root = (Map<String, Object>) new GSONTools(new DefaultTypeFactory()).deserialize(jsonContent);
+	}
+	
+	/**
+	 * Parses the AASs from the JSON
+	 * 
+	 * @return the AASs parsed from the JSON
+	 */
+	@SuppressWarnings("unchecked")
+	public List<AssetAdministrationShell> parseAAS() {
+		assetBuf = parseAssets();
+		return ((List<Object>) root.get(MetamodelToJSONConverter.ASSET_ADMINISTRATION_SHELLS)).stream()
+				.map(this::parseAssetAdministrationShell).collect(Collectors.toList());
+	}
+
+	@SuppressWarnings("unchecked")
+	private AssetAdministrationShell parseAssetAdministrationShell(Object mapObject) {
+		AssetAdministrationShell parsedAAS = AssetAdministrationShell.createAsFacade((Map<String, Object>) mapObject);
+		// Fix Asset - Asset in json-Serialization is just a reference 
+		Map<String, Object> assetRefMap = (Map<String, Object>) parsedAAS.get(AssetAdministrationShell.ASSET);
+		if (assetRefMap.get(Reference.KEY) == null && assetRefMap.get(Asset.KIND) != null) {
+			// => Is already an asset, => does not need to be fixed
+			return parsedAAS;
+		}
+		parsedAAS.put(AssetAdministrationShell.ASSETREF, assetRefMap);
+		
+		// Now try to find the Asset and add it to the AssetAdministrationShell
+		IReference assetRef = parsedAAS.getAssetReference();
+		IKey lastKey = assetRef.getKeys().get(assetRef.getKeys().size() - 1);
+		String idValue = lastKey.getValue();
+		for (Asset asset : assetBuf) {
+			if (asset.getIdentification().getId().equals(idValue)) {
+				parsedAAS.put(AssetAdministrationShell.ASSET, asset);
+				break;
+			}
+		}
+
+		return parsedAAS;
+	}
+	
+	/**
+	 * Parses the Submodels from the JSON
+	 * 
+	 * @return the Submodels parsed from the JSON
+	 */
+	@SuppressWarnings("unchecked")
+	public List<Submodel> parseSubmodels() {
+		return ((List<Object>) root.get(MetamodelToJSONConverter.SUBMODELS)).stream()
+				.map(i -> Submodel.createAsFacade((Map<String, Object>) i)).collect(Collectors.toList());
+	}
+	
+	/**
+	 * Parses the Assets from the JSON
+	 * 
+	 * @return the Assets parsed from the JSON
+	 */
+	@SuppressWarnings("unchecked")
+	public List<Asset> parseAssets() {
+		return ((List<Object>) root.get(MetamodelToJSONConverter.ASSETS)).stream()
+				.map(i -> Asset.createAsFacade((Map<String, Object>) i)).collect(Collectors.toList());
+	}
+
+	/**
+	 * Parses the ConceptDescriptions from the JSON
+	 * 
+	 * @return the ConceptDescriptions parsed from the JSON
+	 */
+	@SuppressWarnings("unchecked")
+	public List<ConceptDescription> parseConceptDescriptions() {
+		return ((List<Object>) root.get(MetamodelToJSONConverter.CONCEPT_DESCRIPTIONS)).stream()
+				.map(i -> ConceptDescription.createAsFacade((Map<String, Object>) i)).collect(Collectors.toList());
+	}
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/factory/json/MetamodelToJSONConverter.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/factory/json/MetamodelToJSONConverter.java
new file mode 100644
index 0000000..80a9afb
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/factory/json/MetamodelToJSONConverter.java
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.aas.factory.json;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.map.parts.Asset;
+import org.eclipse.basyx.submodel.metamodel.facade.SubmodelElementMapCollectionConverter;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.parts.ConceptDescription;
+import org.eclipse.basyx.vab.coder.json.serialization.DefaultTypeFactory;
+import org.eclipse.basyx.vab.coder.json.serialization.GSONTools;
+
+/**
+ * This class can be used to build JSON from Metamodel Objects
+ * 
+ * @author conradi
+ *
+ */
+public class MetamodelToJSONConverter {	
+	
+	public static final String ASSET_ADMINISTRATION_SHELLS = "assetAdministrationShells";
+	public static final String SUBMODELS = "submodels";
+	public static final String ASSETS = "assets";
+	public static final String CONCEPT_DESCRIPTIONS = "conceptDescriptions";
+
+	/**
+	 * Builds the JSON for the given metamodel Objects.
+	 * Not required parameters can be null.
+	 * 
+	 * @param aasList the AASs to build the JSON for
+	 * @param assetList the Assets to build the JSON for
+	 * @param conceptDescriptionList the ConceptDescriptions to build the JSON for
+	 * @param submodelList the Submodels to build the JSON for
+	 */
+	public static String convertToJSON(Collection<AssetAdministrationShell> aasList, Collection<Asset> assetList, 
+			Collection<ConceptDescription> conceptDescriptionList, Collection<Submodel> submodelList) {
+		
+		// The Submodel-Object holds SubmodelElements in a Map<IdShort, SMElement>
+		// The JSON-Schema requires the SubmodelElements to be in a List
+		// This conversion is done by converting the sm to a Map
+		List<Object> smMapList;
+		if(submodelList != null) {
+			smMapList = submodelList.stream()
+					.map(sm -> SubmodelElementMapCollectionConverter.smToMap(sm)).collect(Collectors.toList());
+		} else {
+			smMapList = new ArrayList<>();
+		}
+		
+		
+		Map<String, Object> root = new HashMap<>();
+		
+		root.put(ASSET_ADMINISTRATION_SHELLS, aasList==null ? new ArrayList<AssetAdministrationShell>() : aasList);
+		root.put(SUBMODELS, smMapList);
+		root.put(ASSETS, assetList==null ? new ArrayList<Asset>() : assetList);
+		root.put(CONCEPT_DESCRIPTIONS, conceptDescriptionList==null ? new ArrayList<ConceptDescription>() : conceptDescriptionList);
+		
+		return new GSONTools(new DefaultTypeFactory()).serialize(root);
+	}	
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/factory/xml/MetamodelToXMLConverter.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/factory/xml/MetamodelToXMLConverter.java
index 77ba372..40ce6df 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/factory/xml/MetamodelToXMLConverter.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/factory/xml/MetamodelToXMLConverter.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.aas.factory.xml;
 
 import java.util.Collection;
@@ -18,7 +27,7 @@
 import org.eclipse.basyx.aas.metamodel.api.parts.asset.IAsset;
 import org.eclipse.basyx.submodel.factory.xml.api.parts.ConceptDescriptionXMLConverter;
 import org.eclipse.basyx.submodel.factory.xml.converters.SubmodelXMLConverter;
-import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
 import org.eclipse.basyx.submodel.metamodel.api.parts.IConceptDescription;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
@@ -38,13 +47,13 @@
 	 * @param aasList the AASs to build the XML for
 	 * @param assetList the Assets to build the XML for
 	 * @param conceptDescriptionList the ConceptDescriptions to build the XML for
-	 * @param submodelList the SubModels to build the XML for
+	 * @param submodelList the Submodels to build the XML for
 	 * @param result a Result object to write the XML to e.g. ResultStream
 	 * @throws TransformerException
 	 * @throws ParserConfigurationException
 	 */
 	public static void convertToXML(Collection<IAssetAdministrationShell> aasList, Collection<IAsset> assetList, 
-			Collection<IConceptDescription> conceptDescriptionList, Collection<ISubModel> submodelList, Result result)
+			Collection<IConceptDescription> conceptDescriptionList, Collection<ISubmodel> submodelList, Result result)
 					throws TransformerException, ParserConfigurationException {
 		
 		DocumentBuilderFactory documentFactory = DocumentBuilderFactory.newInstance();
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/factory/xml/XMLToMetamodelConverter.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/factory/xml/XMLToMetamodelConverter.java
index fb8e500..fbd3af1 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/factory/xml/XMLToMetamodelConverter.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/factory/xml/XMLToMetamodelConverter.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.aas.factory.xml;
 
 import java.io.IOException;
@@ -13,7 +22,7 @@
 import org.eclipse.basyx.aas.metamodel.api.parts.asset.IAsset;
 import org.eclipse.basyx.submodel.factory.xml.api.parts.ConceptDescriptionXMLConverter;
 import org.eclipse.basyx.submodel.factory.xml.converters.SubmodelXMLConverter;
-import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
 import org.eclipse.basyx.submodel.metamodel.api.parts.IConceptDescription;
 import org.eclipse.basyx.vab.factory.xml.XmlParser;
 import org.xml.sax.SAXException;
@@ -80,15 +89,15 @@
 
 	
 	/**
-	 * Parses the SubModels form the XML
+	 * Parses the Submodels form the XML
 	 * 
-	 * @return the SubModels parsed form the XML
+	 * @return the Submodels parsed form the XML
 	 * @throws ParserConfigurationException
 	 * @throws SAXException
 	 * @throws IOException
 	 */
 	@SuppressWarnings("unchecked")
-	public List<ISubModel> parseSubmodels() {
+	public List<ISubmodel> parseSubmodels() {
 		Map<String, Object> xmlSubmodels = (Map<String, Object>) root.get(SubmodelXMLConverter.SUBMODELS);		
 		return SubmodelXMLConverter.parseSubmodels(xmlSubmodels);		
 	}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/factory/xml/api/parts/AssetXMLConverter.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/factory/xml/api/parts/AssetXMLConverter.java
index 269a452..c152b15 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/factory/xml/api/parts/AssetXMLConverter.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/factory/xml/api/parts/AssetXMLConverter.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.aas.factory.xml.api.parts;
 
 import java.util.ArrayList;
@@ -5,17 +14,22 @@
 import java.util.List;
 import java.util.Map;
 
+import org.eclipse.basyx.aas.metamodel.api.parts.asset.AssetKind;
 import org.eclipse.basyx.aas.metamodel.api.parts.asset.IAsset;
 import org.eclipse.basyx.aas.metamodel.map.parts.Asset;
 import org.eclipse.basyx.submodel.factory.xml.XMLHelper;
 import org.eclipse.basyx.submodel.factory.xml.converters.qualifier.HasDataSpecificationXMLConverter;
 import org.eclipse.basyx.submodel.factory.xml.converters.qualifier.IdentifiableXMLConverter;
-import org.eclipse.basyx.submodel.factory.xml.converters.qualifier.haskind.HasKindXMLConverter;
 import org.eclipse.basyx.submodel.factory.xml.converters.reference.ReferenceXMLConverter;
 import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasDataSpecification;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Identifiable;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 
+import com.google.common.base.Strings;
+
 /**
  * Handles the conversion between IAsset objects and the XML tag &lt;aas:assets&gt; in both directions
  * 
@@ -43,9 +57,9 @@
 		for (Map<String, Object> xmlAsset : xmlAssets) {
 			Asset asset = new Asset();
 			
-			IdentifiableXMLConverter.populateIdentifiable(xmlAsset, asset);
-			HasDataSpecificationXMLConverter.populateHasDataSpecification(xmlAsset, asset);
-			HasKindXMLConverter.populateHasKind(xmlAsset, asset);
+			IdentifiableXMLConverter.populateIdentifiable(xmlAsset, Identifiable.createAsFacadeNonStrict(asset, KeyElements.ASSET));
+			HasDataSpecificationXMLConverter.populateHasDataSpecification(xmlAsset, HasDataSpecification.createAsFacade(asset));
+			asset.setAssetKind(parseAssetKind(xmlAsset));
 			
 			if(xmlAsset.containsKey(ASSET_IDENTIFICATION_MODEL_REF)) {
 				asset.setAssetIdentificationModel(parseAssetIdentificationModelRef(xmlAsset));
@@ -69,6 +83,22 @@
 		return ReferenceXMLConverter.parseReference(semanticIDObj);
 	}
 	
+
+	/**
+	 * Parses &lt;aas:akind&gt; and gets the correct AssetKind from it
+	 * 
+	 * @param xmlObject a Map containing the XML tag &lt;aas:kind&gt;
+	 * @return the parsed AssetKind or null if none was present
+	 */
+	private static AssetKind parseAssetKind(Map<String, Object> xmlObject) {
+		String assetKindValue = XMLHelper.getString(xmlObject.get(ASSET_KIND));
+		if (!Strings.isNullOrEmpty(assetKindValue)) {
+			return AssetKind.fromString(assetKindValue);
+		} else {
+			throw new RuntimeException("Necessary value 'AssetKind' was not found for one of the Assets in the XML file.");
+		}
+	}
+	
 	
 	
 	/**
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/factory/xml/api/parts/ViewXMLConverter.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/factory/xml/api/parts/ViewXMLConverter.java
index 8202449..f6827c4 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/factory/xml/api/parts/ViewXMLConverter.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/factory/xml/api/parts/ViewXMLConverter.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.aas.factory.xml.api.parts;
 
 import java.util.ArrayList;
@@ -15,6 +24,10 @@
 import org.eclipse.basyx.submodel.factory.xml.converters.qualifier.ReferableXMLConverter;
 import org.eclipse.basyx.submodel.factory.xml.converters.reference.ReferenceXMLConverter;
 import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasDataSpecification;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasSemantics;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 
@@ -51,9 +64,9 @@
 		for(Map<String, Object> xmlView: xmlViewList) {
 			View view = new View();
 			
-			ReferableXMLConverter.populateReferable(xmlView, view);
-			HasSemanticsXMLConverter.populateHasSemantics(xmlView, view);
-			HasDataSpecificationXMLConverter.populateHasDataSpecification(xmlView, view);
+			ReferableXMLConverter.populateReferable(xmlView, Referable.createAsFacadeNonStrict(view, KeyElements.VIEW));
+			HasSemanticsXMLConverter.populateHasSemantics(xmlView, HasSemantics.createAsFacade(view));
+			HasDataSpecificationXMLConverter.populateHasDataSpecification(xmlView, HasDataSpecification.createAsFacade(view));
 			
 			Map<String, Object> xmlContainedElementsObject = ((Map<String, Object>) xmlView.get(CONTAINED_ELEMENTS));
 			Map<String, Object> xmlContainedElementObject = (Map<String, Object>) xmlContainedElementsObject.get(CONTAINED_ELEMENT_REF);
@@ -119,4 +132,4 @@
 			xmlView.appendChild(xmlContainedElements);
 		}
 	}
-}
\ No newline at end of file
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/factory/xml/converters/AssetAdministrationShellXMLConverter.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/factory/xml/converters/AssetAdministrationShellXMLConverter.java
index 79ad580..7d95a57 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/factory/xml/converters/AssetAdministrationShellXMLConverter.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/factory/xml/converters/AssetAdministrationShellXMLConverter.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.aas.factory.xml.converters;
 
 import java.util.ArrayList;
@@ -22,6 +31,9 @@
 import org.eclipse.basyx.submodel.metamodel.api.reference.IKey;
 import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
 import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasDataSpecification;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Identifiable;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
 import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
@@ -62,8 +74,8 @@
 		for(Map<String, Object> xmlAAS: xmlAASs) {
 			AssetAdministrationShell adminShell = new AssetAdministrationShell();
 			
-			IdentifiableXMLConverter.populateIdentifiable(xmlAAS, adminShell);
-			HasDataSpecificationXMLConverter.populateHasDataSpecification(xmlAAS, adminShell);
+			IdentifiableXMLConverter.populateIdentifiable(xmlAAS, Identifiable.createAsFacadeNonStrict(adminShell, KeyElements.ASSETADMINISTRATIONSHELL));
+			HasDataSpecificationXMLConverter.populateHasDataSpecification(xmlAAS, HasDataSpecification.createAsFacade(adminShell));
 			
 			Collection<IView> views = ViewXMLConverter.parseViews(xmlAAS);
 			Collection<IConceptDictionary> conceptDictionary = parseConceptDictionaries(xmlAAS, conceptDescriptions);
@@ -133,7 +145,7 @@
 		List<Map<String, Object>> xmlConceptDictionaryList = XMLHelper.getList(xmlConceptDictionaries.get(CONCEPT_DICTIONARY));
 		for (Map<String, Object> xmlConceptDictionary : xmlConceptDictionaryList) {
 			ConceptDictionary conceptDictionary = new ConceptDictionary();
-			ReferableXMLConverter.populateReferable(xmlConceptDictionary, conceptDictionary);
+			ReferableXMLConverter.populateReferable(xmlConceptDictionary, Referable.createAsFacadeNonStrict(conceptDictionary, KeyElements.CONCEPTDICTIONARY));
 			
 			Map<String, Object> xmlConceptDescriptionRefs = (Map<String, Object>) xmlConceptDictionary.get(CONCEPT_DESCRIPTION_REFS);
 			HashSet<IReference> referenceSet = new HashSet<>();
@@ -305,4 +317,4 @@
 		return conceptDicts;
 	}
 
-}
\ No newline at end of file
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/manager/ConnectedAssetAdministrationShellManager.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/manager/ConnectedAssetAdministrationShellManager.java
index 2b95057..aeae53b 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/manager/ConnectedAssetAdministrationShellManager.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/manager/ConnectedAssetAdministrationShellManager.java
@@ -10,24 +10,26 @@
 import java.util.Map;
 
 import org.eclipse.basyx.aas.aggregator.proxy.AASAggregatorProxy;
+import org.eclipse.basyx.aas.aggregator.restapi.AASAggregatorProvider;
 import org.eclipse.basyx.aas.manager.api.IAssetAdministrationShellManager;
 import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
 import org.eclipse.basyx.aas.metamodel.connected.ConnectedAssetAdministrationShell;
 import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
 import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
 import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
-import org.eclipse.basyx.aas.registration.api.IAASRegistryService;
-import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
 import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
-import org.eclipse.basyx.submodel.metamodel.connected.ConnectedSubModel;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.submodel.metamodel.connected.ConnectedSubmodel;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.restapi.SubmodelProvider;
 import org.eclipse.basyx.vab.exception.FeatureNotImplementedException;
 import org.eclipse.basyx.vab.factory.java.ModelProxyFactory;
 import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
 import org.eclipse.basyx.vab.modelprovider.VABPathTools;
 import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
-import org.eclipse.basyx.vab.protocol.api.IConnectorProvider;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
+import org.eclipse.basyx.vab.protocol.api.IConnectorFactory;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorFactory;
 
 /**
  * Implement a AAS manager backend that communicates via HTTP/REST<br />
@@ -38,8 +40,8 @@
  */
 public class ConnectedAssetAdministrationShellManager implements IAssetAdministrationShellManager {
 
-	protected IAASRegistryService aasDirectory;
-	protected IConnectorProvider connectorProvider;
+	protected IAASRegistry aasDirectory;
+	protected IConnectorFactory connectorFactory;
 	protected ModelProxyFactory proxyFactory;
 
 	/**
@@ -47,75 +49,59 @@
 	 * 
 	 * @param directory
 	 */
-	public ConnectedAssetAdministrationShellManager(IAASRegistryService directory) {
-		this(directory, new HTTPConnectorProvider());
+	public ConnectedAssetAdministrationShellManager(IAASRegistry directory) {
+		this(directory, new HTTPConnectorFactory());
 	}
 
 	/**
 	 * @param networkDirectoryService
 	 * @param providerProvider
 	 */
-	public ConnectedAssetAdministrationShellManager(IAASRegistryService directory,
-			IConnectorProvider provider) {
+	public ConnectedAssetAdministrationShellManager(IAASRegistry directory,
+			IConnectorFactory provider) {
 		this.aasDirectory = directory;
-		this.connectorProvider = provider;
+		this.connectorFactory = provider;
 		this.proxyFactory = new ModelProxyFactory(provider);
 	}
 
 	@Override
-	public ISubModel retrieveSubModel(IIdentifier aasId, IIdentifier smId) {
-		// look up AAS descriptor in the registry
-		AASDescriptor aasDescriptor = aasDirectory.lookupAAS(aasId);
-
-		// Get submodel descriptor from the aas descriptor
-		SubmodelDescriptor smDescriptor = aasDescriptor.getSubModelDescriptorFromIdentifierId(smId.getId());
+	public ISubmodel retrieveSubmodel(IIdentifier aasId, IIdentifier smId) {
+		// look up SM descriptor in the registry
+		SubmodelDescriptor smDescriptor = aasDirectory.lookupSubmodel(aasId, smId);
 
 		// get address of the submodel descriptor
 		String addr = smDescriptor.getFirstEndpoint();
 
 		// Return a new VABElementProxy
-		return new ConnectedSubModel(proxyFactory.createProxy(addr));
+		return new ConnectedSubmodel(proxyFactory.createProxy(addr));
 	}
 
 	@Override
-	public ConnectedAssetAdministrationShell retrieveAAS(IIdentifier aasId) throws Exception {
+	public ConnectedAssetAdministrationShell retrieveAAS(IIdentifier aasId) {
 		VABElementProxy proxy = getAASProxyFromId(aasId);
-		return new ConnectedAssetAdministrationShell(proxy, this);
+		return new ConnectedAssetAdministrationShell(proxy);
 	}
 
 	@Override
-	public Map<String, ISubModel> retrieveSubmodels(IIdentifier aasId) {
+	public Map<String, ISubmodel> retrieveSubmodels(IIdentifier aasId) {
 		AASDescriptor aasDesc = aasDirectory.lookupAAS(aasId);
-		Collection<SubmodelDescriptor> smDescriptors = aasDesc.getSubModelDescriptors();
-		Map<String, ISubModel> submodels = new HashMap<>();
+		Collection<SubmodelDescriptor> smDescriptors = aasDesc.getSubmodelDescriptors();
+		Map<String, ISubmodel> submodels = new HashMap<>();
 		for (SubmodelDescriptor smDesc : smDescriptors) {
 			String smEndpoint = smDesc.getFirstEndpoint();
 			String smIdShort = smDesc.getIdShort();
 			VABElementProxy smProxy = proxyFactory.createProxy(smEndpoint);
-			ConnectedSubModel connectedSM = new ConnectedSubModel(smProxy);
+			ConnectedSubmodel connectedSM = new ConnectedSubmodel(smProxy);
 			submodels.put(smIdShort, connectedSM);
 		}
 		return submodels;
 	}
 
-	@Override
-	public void createAAS(AssetAdministrationShell aas, IIdentifier aasId, String endpoint) {
-		IModelProvider provider = connectorProvider.getConnector(endpoint);
-		AASAggregatorProxy proxy = new AASAggregatorProxy(provider);
-		proxy.createAAS(aas);
-		try {
-			String combinedEndpoint = VABPathTools.concatenatePaths(endpoint, "aasList", URLEncoder.encode(aas.getIdentification().getId(), "UTF-8"), "aas");
-			aasDirectory.register(new AASDescriptor(aas, combinedEndpoint));
-		} catch (UnsupportedEncodingException e) {
-			throw new RuntimeException("Encoding failed. This should never happen");
-		}
-	}
-
 	private VABElementProxy getAASProxyFromId(IIdentifier aasId) {
 		// Lookup AAS descriptor
 		AASDescriptor aasDescriptor = aasDirectory.lookupAAS(aasId);
 
-		// Get AAD address from AAS descriptor
+		// Get AAS address from AAS descriptor
 		String addr = aasDescriptor.getFirstEndpoint();
 
 		// Return a new VABElementProxy
@@ -128,19 +114,32 @@
 	}
 
 	@Override
-	public void deleteAAS(String id) throws Exception {
-		throw new FeatureNotImplementedException();
+	public void deleteAAS(IIdentifier id) {
+		// Lookup AAS descriptor
+		AASDescriptor aasDescriptor = aasDirectory.lookupAAS(id);
+
+		// Get AAS address from AAS descriptor
+		String addr = aasDescriptor.getFirstEndpoint();
+
+		// Address ends in "/aas", has to be stripped for removal
+		addr = VABPathTools.stripSlashes(addr);
+		addr = addr.substring(0, addr.length() - "/aas".length());
+
+		// Delete from server
+		proxyFactory.createProxy(addr).deleteValue("");
+
+		// Delete from Registry
+		aasDirectory.delete(id);
+
+		// TODO: How to handle submodels -> Lifecycle needs to be clarified
 	}
 
 	@Override
-	public void createSubModel(IIdentifier aasId, SubModel submodel) {
+	public void createSubmodel(IIdentifier aasId, Submodel submodel) {
 		
 		// Push the SM to the server using the ConnectedAAS
-		try {
-			retrieveAAS(aasId).addSubModel(submodel);
-		} catch (Exception e) {
-			throw new RuntimeException("Could not create Submodel on server", e);
-		}
+
+		retrieveAAS(aasId).addSubmodel(submodel);
 		
 		// Lookup AAS descriptor
 		AASDescriptor aasDescriptor = aasDirectory.lookupAAS(aasId);
@@ -149,7 +148,34 @@
 		String addr = aasDescriptor.getFirstEndpoint();
 		
 		// Register the SM
-		String smEndpoint = VABPathTools.concatenatePaths(addr, AssetAdministrationShell.SUBMODELS, submodel.getIdShort());
+		String smEndpoint = VABPathTools.concatenatePaths(addr, AssetAdministrationShell.SUBMODELS, submodel.getIdShort(), SubmodelProvider.SUBMODEL);
 		aasDirectory.register(aasId, new SubmodelDescriptor(submodel, smEndpoint));
 	}
+
+	@Override
+	public void deleteSubmodel(IIdentifier aasId, IIdentifier submodelId) {
+		IAssetAdministrationShell shell = retrieveAAS(aasId);
+		shell.removeSubmodel(submodelId);
+
+		aasDirectory.delete(aasId, submodelId);
+	}
+
+	@Override
+	public void createAAS(AssetAdministrationShell aas, String endpoint) {
+		endpoint = VABPathTools.stripSlashes(endpoint);
+		if (!endpoint.endsWith(AASAggregatorProvider.PREFIX)) {
+			endpoint += "/" + AASAggregatorProvider.PREFIX;
+		}
+
+		IModelProvider provider = connectorFactory.getConnector(endpoint);
+		AASAggregatorProxy proxy = new AASAggregatorProxy(provider);
+		proxy.createAAS(aas);
+		try {
+
+			String combinedEndpoint = VABPathTools.concatenatePaths(endpoint, URLEncoder.encode(aas.getIdentification().getId(), "UTF-8"), "aas");
+			aasDirectory.register(new AASDescriptor(aas, combinedEndpoint));
+		} catch (UnsupportedEncodingException e) {
+			throw new RuntimeException("Encoding failed. This should never happen");
+		}
+	}
 }
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/manager/api/IAssetAdministrationShellManager.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/manager/api/IAssetAdministrationShellManager.java
index 3877084..cc6420a 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/manager/api/IAssetAdministrationShellManager.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/manager/api/IAssetAdministrationShellManager.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.aas.manager.api;
 
 import java.util.Collection;
@@ -5,9 +14,9 @@
 
 import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
 import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
-import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
 import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
 
 
 
@@ -29,28 +38,40 @@
 	public Collection<IAssetAdministrationShell> retrieveAASAll();
 	
 	/**
-	 * Creates an AAS on a remote server.
+	 * Creates an AAS on a remote server
+	 * 
+	 * @param aas
+	 * @param aasId
+	 * @param endpoint
 	 */
-	void createAAS(AssetAdministrationShell aas, IIdentifier aasId, String endpoint);
-	
+	void createAAS(AssetAdministrationShell aas, String endpoint);
+
 	/**
 	 * Unlink an AAS from the system
 	 */
-	void deleteAAS(String id) throws Exception;
+	void deleteAAS(IIdentifier id) throws Exception;
 
 	/**
 	 * Retrieves a submodel
 	 */
-	ISubModel retrieveSubModel(IIdentifier aasId, IIdentifier subModelId);
+	ISubmodel retrieveSubmodel(IIdentifier aasId, IIdentifier subModelId);
 
 	/**
 	 * Creates a submodel on a remote server. Assumes that the AAS is already
 	 * registered in the directory
 	 */
-	void createSubModel(IIdentifier aasId, SubModel submodel);
+	void createSubmodel(IIdentifier aasId, Submodel submodel);
+
+	/**
+	 * Deletes a submodel on a remote server and removes its registry entry
+	 * 
+	 * @param aasId
+	 * @param submodelId
+	 */
+	void deleteSubmodel(IIdentifier aasId, IIdentifier submodelId);
 
 	/**
 	 * Retrieves all submodels in a specific AAS
 	 */
-	Map<String, ISubModel> retrieveSubmodels(IIdentifier aasId);
+	Map<String, ISubmodel> retrieveSubmodels(IIdentifier aasId);
 }
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/api/IAasEnv.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/api/IAasEnv.java
new file mode 100644
index 0000000..06115aa
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/api/IAasEnv.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.aas.metamodel.api;
+
+import java.util.Collection;
+
+import org.eclipse.basyx.aas.metamodel.api.parts.asset.IAsset;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.api.parts.IConceptDescription;
+
+public interface IAasEnv {
+
+	Collection<IAsset> getAssets();
+	
+	Collection<IAssetAdministrationShell> getAssetAdministrationShells();
+	
+	Collection<ISubmodel> getSubmodels();
+	
+	Collection<IConceptDescription> getConceptDescriptions();
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/api/IAssetAdministrationShell.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/api/IAssetAdministrationShell.java
index 3514971..46710c7 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/api/IAssetAdministrationShell.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/api/IAssetAdministrationShell.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.aas.metamodel.api;
 
 import java.util.Collection;
@@ -8,11 +17,12 @@
 import org.eclipse.basyx.aas.metamodel.api.parts.asset.IAsset;
 import org.eclipse.basyx.aas.metamodel.api.security.ISecurity;
 import org.eclipse.basyx.submodel.metamodel.api.IElement;
-import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
 import org.eclipse.basyx.submodel.metamodel.api.qualifier.IHasDataSpecification;
 import org.eclipse.basyx.submodel.metamodel.api.qualifier.IIdentifiable;
 import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
 
 /**
  * Asset Administration Shell (AAS) interface
@@ -25,9 +35,9 @@
 	/**
 	 * Return all registered submodels of this AAS
 	 * 
-	 * @return
+	 * @return IdShort -> ISubmodel
 	 */
-	public Map<String, ISubModel> getSubModels();
+	public Map<String, ISubmodel> getSubmodels();
 
 	/**
 	 * Return the references to all registered submodels
@@ -37,12 +47,26 @@
 	public Collection<IReference> getSubmodelReferences();
 
 	/**
-	 * Add a sub model to the AAS
+	 * Add a submodel to the AAS
 	 * 
 	 * @param subModel
 	 *            The added sub model
 	 */
-	public void addSubModel(SubModel subModel);
+	public void addSubmodel(Submodel subModel);
+
+	/**
+	 * Removes a submodel from the AAS
+	 * 
+	 * @param id
+	 */
+	public void removeSubmodel(IIdentifier id);
+
+	/**
+	 * Gets a submodel from the AAS
+	 * 
+	 * @param id
+	 */
+	public ISubmodel getSubmodel(IIdentifier id);
 
 	/**
 	 * Gets the definition of the security relevant aspects of the AAS.
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/api/parts/IConceptDictionary.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/api/parts/IConceptDictionary.java
index cf76055..217d510 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/api/parts/IConceptDictionary.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/api/parts/IConceptDictionary.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.aas.metamodel.api.parts;
 
 import java.util.Collection;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/api/parts/IView.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/api/parts/IView.java
index ea951f1..9ec0cd0 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/api/parts/IView.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/api/parts/IView.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.aas.metamodel.api.parts;
 
 import java.util.Collection;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/api/parts/asset/AssetKind.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/api/parts/asset/AssetKind.java
index 5028960..31b2030 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/api/parts/asset/AssetKind.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/api/parts/asset/AssetKind.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.aas.metamodel.api.parts.asset;
 
 import org.eclipse.basyx.submodel.metamodel.enumhelper.StandardizedLiteralEnum;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/api/parts/asset/IAsset.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/api/parts/asset/IAsset.java
index b7b729c..a9af5ed 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/api/parts/asset/IAsset.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/api/parts/asset/IAsset.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.aas.metamodel.api.parts.asset;
 
 import org.eclipse.basyx.submodel.metamodel.api.qualifier.IHasDataSpecification;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/api/policypoints/IAccessControlPolicyPoints.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/api/policypoints/IAccessControlPolicyPoints.java
index c804dfd..248188f 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/api/policypoints/IAccessControlPolicyPoints.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/api/policypoints/IAccessControlPolicyPoints.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.aas.metamodel.api.policypoints;
 
 /**
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/api/security/ICertificate.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/api/security/ICertificate.java
index 5113e5d..8ac3316 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/api/security/ICertificate.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/api/security/ICertificate.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.aas.metamodel.api.security;
 
 /**
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/api/security/ISecurity.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/api/security/ISecurity.java
index 8fba5b4..60abcbf 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/api/security/ISecurity.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/api/security/ISecurity.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.aas.metamodel.api.security;
 
 import org.eclipse.basyx.aas.metamodel.api.policypoints.IAccessControlPolicyPoints;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/connected/ConnectedAssetAdministrationShell.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/connected/ConnectedAssetAdministrationShell.java
index 59eaa58..a804400 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/connected/ConnectedAssetAdministrationShell.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/connected/ConnectedAssetAdministrationShell.java
@@ -1,10 +1,20 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.aas.metamodel.connected;
 
 import java.util.Collection;
+import java.util.HashMap;
 import java.util.Map;
+import java.util.Optional;
 import java.util.stream.Collectors;
 
-import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
 import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
 import org.eclipse.basyx.aas.metamodel.api.parts.IConceptDictionary;
 import org.eclipse.basyx.aas.metamodel.api.parts.IView;
@@ -15,43 +25,52 @@
 import org.eclipse.basyx.aas.metamodel.map.parts.ConceptDictionary;
 import org.eclipse.basyx.aas.metamodel.map.parts.View;
 import org.eclipse.basyx.aas.metamodel.map.security.Security;
-import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
 import org.eclipse.basyx.submodel.metamodel.api.dataspecification.IEmbeddedDataSpecification;
 import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
 import org.eclipse.basyx.submodel.metamodel.api.qualifier.IAdministrativeInformation;
 import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
 import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
 import org.eclipse.basyx.submodel.metamodel.connected.ConnectedElement;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.submodel.metamodel.connected.ConnectedSubmodel;
+import org.eclipse.basyx.submodel.metamodel.facade.SubmodelElementMapCollectionConverter;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
 import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasDataSpecification;
 import org.eclipse.basyx.submodel.metamodel.map.qualifier.Identifiable;
 import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangStrings;
 import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
 import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
 import org.eclipse.basyx.submodel.metamodel.map.reference.ReferenceHelper;
+import org.eclipse.basyx.submodel.restapi.SubmodelProvider;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
 import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+import org.eclipse.basyx.vab.modelprovider.VABPathTools;
 
 /**
  * "Connected" implementation of IAssetAdministrationShell
  * 
- * @author rajashek, Zai Zhang
+ * @author rajashek, Zai Zhang, schnicke
  *
  */
 public class ConnectedAssetAdministrationShell extends ConnectedElement implements IAssetAdministrationShell {
-
-	ConnectedAssetAdministrationShellManager manager;
+	/**
+	 * Constructor creating a ConnectedAAS pointing to the AAS represented by proxy
+	 * 
+	 * @param proxy
+	 */
+	public ConnectedAssetAdministrationShell(VABElementProxy proxy) {
+		super(proxy);
+	}
 
 	/**
 	 * Constructor creating a ConnectedAAS pointing to the AAS represented by proxy
-	 * and path
+	 * and an already cached local copy
 	 * 
-	 * @param path
 	 * @param proxy
-	 * @param manager
+	 * @param localCopy
 	 */
-	public ConnectedAssetAdministrationShell(VABElementProxy proxy, ConnectedAssetAdministrationShellManager manager) {
+	public ConnectedAssetAdministrationShell(VABElementProxy proxy, AssetAdministrationShell localCopy) {
 		super(proxy);
-		this.manager = manager;
 	}
 
 	/**
@@ -118,15 +137,28 @@
 		return set.stream().map(ConceptDictionary::createAsFacade).collect(Collectors.toSet());
 	}
 
+	@SuppressWarnings("unchecked")
 	@Override
-	public Map<String, ISubModel> getSubModels() {
-		return manager.retrieveSubmodels(getIdentification());
+	public Map<String, ISubmodel> getSubmodels() {
+		Collection<Map<String, Object>> submodelCollection = (Collection<Map<String, Object>>) getProxy().getValue(AssetAdministrationShell.SUBMODELS);
+
+		Map<String, ISubmodel> ret = new HashMap<>();
+
+		for (Map<String, Object> m : submodelCollection) {
+			Submodel sm = Submodel.createAsFacade(m);
+			String path = VABPathTools.concatenatePaths(AssetAdministrationShell.SUBMODELS, sm.getIdShort(), SubmodelProvider.SUBMODEL);
+			ret.put(sm.getIdShort(), new ConnectedSubmodel(getProxy().getDeepProxy(path), sm));
+		}
+
+		return ret;
 	}
 
 	@Override
-	public void addSubModel(SubModel subModel) {
+	public void addSubmodel(Submodel subModel) {
 		subModel.setParent(getReference());
-		getProxy().createValue("/submodels", subModel);
+		Map<String, Object> convertedMap = SubmodelElementMapCollectionConverter.smToMap(subModel);
+		String accessPath = VABPathTools.concatenatePaths(AssetAdministrationShell.SUBMODELS, subModel.getIdShort());
+		getProxy().setValue(accessPath, convertedMap);
 	}
 
 	@Override
@@ -169,4 +201,32 @@
 	public IReference getReference() {
 		return Identifiable.createAsFacade(getElem(), getKeyElement()).getReference();
 	}
+
+	/**
+	 * Returns a local copy of the AAS, i.e. a snapshot of the current state. <br>
+	 * No changes of this copy are reflected in the remote AAS
+	 * 
+	 * @return the local copy
+	 */
+	public AssetAdministrationShell getLocalCopy() {
+		return AssetAdministrationShell.createAsFacade(getElem());
+	}
+
+	@Override
+	public void removeSubmodel(IIdentifier id) {
+		ISubmodel sm = getSubmodel(id);
+
+		String path = VABPathTools.concatenatePaths(AssetAdministrationShell.SUBMODELS, sm.getIdShort());
+		getProxy().deleteValue(path);
+	}
+
+	@Override
+	public ISubmodel getSubmodel(IIdentifier id) {
+		// FIXME: Change this when AAS API supports Submodel retrieval by Identifier
+		Optional<ISubmodel> op = getSubmodels().values().stream().filter(sm -> sm.getIdentification().getId().equals(id.getId())).findFirst();
+		if (!op.isPresent()) {
+			throw new ResourceNotFoundException("AAS " + getIdentification() + " does not have a submodel with id " + id);
+		}
+		return op.get();
+	}
 }
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/exception/MetamodelConstructionException.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/exception/MetamodelConstructionException.java
new file mode 100644
index 0000000..42ede92
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/exception/MetamodelConstructionException.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.aas.metamodel.exception;
+
+import java.util.Map;
+
+/**
+ * This class is used to throw exception when
+ * metamodel's createAsFacade from map does not work
+ * due to absence of mandatory fields
+ * 
+ * @author haque
+ *
+ */
+public class MetamodelConstructionException extends RuntimeException {
+	private static final long serialVersionUID = 1L;
+	
+	public MetamodelConstructionException(Class<?> clazz , Map<String, Object> map) {
+		super("Could not construct meta model element " + clazz.getName() + ". Passed argument was " + map.toString());
+	}
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/AasEnv.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/AasEnv.java
new file mode 100644
index 0000000..3cf7b51
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/AasEnv.java
@@ -0,0 +1,157 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.aas.metamodel.map;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.api.IAasEnv;
+import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.api.parts.asset.IAsset;
+import org.eclipse.basyx.aas.metamodel.map.parts.Asset;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.api.parts.IConceptDescription;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.modeltype.ModelType;
+import org.eclipse.basyx.submodel.metamodel.map.parts.ConceptDescription;
+import org.eclipse.basyx.vab.model.VABModelMap;
+
+/**
+ * AasEnv class 
+ * 
+ * @author gordt
+ */
+
+public class AasEnv extends VABModelMap<Object> implements IAasEnv {
+	
+	public static final String ASSETS = "assets";
+	public static final String ASSETADMINISTRATIONSHELLS = "assetAdministrationShells";
+	public static final String SUBMODELS = "submodels";
+	public static final String CONCEPTDESCRIPTIONS = "conceptDescriptions";
+	public static final String MODELTYPE = "AasEnv";
+
+
+	public AasEnv() {
+		// Add model type
+		putAll(new ModelType(MODELTYPE));
+	}
+
+	/**
+	 * Creates a AssetAdministrationShell object from a map
+	 * 
+	 * @param obj
+	 *            a AssetAdministrationShell object as raw map
+	 * @return a AssetAdministrationShell object, that behaves like a facade for the
+	 *         given map
+	 */
+	@SuppressWarnings("unchecked")
+	public static AasEnv createAsFacade(Map<String, Object> map) {
+		if (map == null) {
+			return null;
+		}
+
+		AasEnv ret = new AasEnv();
+		
+		Collection<IAsset> assetsTarget = new LinkedList<>();
+		if (map.get(ASSETS) != null && map.get(ASSETS) instanceof Collection) {
+			Collection<Map<String, Object>> objectMapCollection = (Collection<Map<String, Object>>) map.get(ASSETS);
+			for(Map<String, Object> objectMap : objectMapCollection) {
+				assetsTarget.add(Asset.createAsFacade(objectMap));
+			}
+		}
+		ret.put(ASSETS, assetsTarget);
+		
+		Collection<IAssetAdministrationShell> aasTarget = new LinkedList<>();
+		if (map.get(ASSETADMINISTRATIONSHELLS) != null && map.get(ASSETADMINISTRATIONSHELLS) instanceof Collection) {
+			Collection<Map<String, Object>> objectMapCollection = (Collection<Map<String, Object>>) map.get(ASSETADMINISTRATIONSHELLS);
+			for(Map<String, Object> objectMap : objectMapCollection) {
+				aasTarget.add(AssetAdministrationShell.createAsFacade(objectMap));
+			}
+		}
+		ret.put(ASSETADMINISTRATIONSHELLS, aasTarget);
+		
+		Collection<ISubmodel> submodelsTarget = new LinkedList<>();
+		if (map.get(SUBMODELS) != null && map.get(SUBMODELS) instanceof Collection) {
+			Collection<Map<String, Object>> objectMapCollection = (Collection<Map<String, Object>>) map.get(SUBMODELS);
+			for(Map<String, Object> objectMap : objectMapCollection) {
+				submodelsTarget.add(Submodel.createAsFacade(objectMap));
+			}
+		}
+		ret.put(SUBMODELS, submodelsTarget);
+		
+		Collection<IConceptDescription> conceptDescriptionsTarget = new LinkedList<>();
+		if (map.get(CONCEPTDESCRIPTIONS) != null && map.get(CONCEPTDESCRIPTIONS) instanceof Collection) {
+			Collection<Map<String, Object>> objectMapCollection = (Collection<Map<String, Object>>) map.get(CONCEPTDESCRIPTIONS);
+			for(Map<String, Object> objectMap : objectMapCollection) {
+				conceptDescriptionsTarget.add(ConceptDescription.createAsFacade(objectMap));
+			}
+		}
+		ret.put(CONCEPTDESCRIPTIONS, conceptDescriptionsTarget);
+		
+		return ret;
+	}
+	
+	
+	
+	@SuppressWarnings("unchecked")
+	@Override
+	public Collection<IAsset> getAssets() {
+		List<IAsset> internal = (List<IAsset>) get(ASSETS);
+		List<IAsset> result = new ArrayList<IAsset>(internal.size());
+		result.addAll(internal);
+		return result;
+	}
+
+	public void setAssets(Collection<IAsset> assets) {
+		put(ASSETS, assets);
+	}
+	
+	@SuppressWarnings("unchecked")
+	@Override
+	public Collection<IAssetAdministrationShell> getAssetAdministrationShells() {
+		List<IAssetAdministrationShell> internal = (List<IAssetAdministrationShell>) get(ASSETADMINISTRATIONSHELLS);
+		List<IAssetAdministrationShell> result = new ArrayList<IAssetAdministrationShell>(internal.size());
+		result.addAll(internal);
+		return result;
+	}
+
+	public void setAssetAdministrationShells(Collection<IAssetAdministrationShell> assetAdministrationShells) {
+		put(ASSETADMINISTRATIONSHELLS, assetAdministrationShells);
+	}
+	
+	@SuppressWarnings("unchecked")
+	@Override
+	public Collection<ISubmodel> getSubmodels() {
+		List<ISubmodel> internal = (List<ISubmodel>) get(SUBMODELS);
+		List<ISubmodel> result = new ArrayList<ISubmodel>(internal.size());
+		result.addAll(internal);
+		return result;
+	}
+
+	public void setSubmodels(Collection<ISubmodel> submodels) {
+		put(SUBMODELS, submodels);
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public Collection<IConceptDescription> getConceptDescriptions() {
+		List<IConceptDescription> internal = (List<IConceptDescription>) get(CONCEPTDESCRIPTIONS);
+		List<IConceptDescription> result = new ArrayList<IConceptDescription>(internal.size());
+		result.addAll(internal);
+		return result;
+	}
+
+	public void setConceptDescriptions(Collection<IConceptDescription> conceptDescriptions) {
+		put(CONCEPTDESCRIPTIONS, conceptDescriptions);
+	}
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/AssetAdministrationShell.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/AssetAdministrationShell.java
index 0ca5f88..969592e 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/AssetAdministrationShell.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/AssetAdministrationShell.java
@@ -1,11 +1,18 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.aas.metamodel.map;
 
-import java.util.Arrays;
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.HashSet;
-import java.util.List;
 import java.util.Map;
 import java.util.stream.Collectors;
 
@@ -14,11 +21,12 @@
 import org.eclipse.basyx.aas.metamodel.api.parts.IView;
 import org.eclipse.basyx.aas.metamodel.api.parts.asset.IAsset;
 import org.eclipse.basyx.aas.metamodel.api.security.ISecurity;
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
 import org.eclipse.basyx.aas.metamodel.map.parts.Asset;
 import org.eclipse.basyx.aas.metamodel.map.parts.ConceptDictionary;
 import org.eclipse.basyx.aas.metamodel.map.parts.View;
 import org.eclipse.basyx.aas.metamodel.map.security.Security;
-import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
 import org.eclipse.basyx.submodel.metamodel.api.dataspecification.IEmbeddedDataSpecification;
 import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
 import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
@@ -26,7 +34,7 @@
 import org.eclipse.basyx.submodel.metamodel.api.qualifier.IAdministrativeInformation;
 import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
 import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
 import org.eclipse.basyx.submodel.metamodel.map.modeltype.ModelType;
 import org.eclipse.basyx.submodel.metamodel.map.qualifier.AdministrativeInformation;
 import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasDataSpecification;
@@ -35,6 +43,7 @@
 import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
 import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
 import org.eclipse.basyx.submodel.metamodel.map.reference.ReferenceHelper;
+import org.eclipse.basyx.vab.exception.FeatureNotImplementedException;
 import org.eclipse.basyx.vab.model.VABModelMap;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -60,18 +69,29 @@
 	public static final String CONCEPTDICTIONARY = "conceptDictionary";
 	public static final String TYPE = "type";
 	public static final String ADDRESS = "address";
-	public static final String ENDPOINTS = "endpoints";
-	public static final String MODELTYPE = "AssetAdministationShell";
+	public static final String MODELTYPE = "AssetAdministrationShell";
 
 	/**
 	 * Constructor
 	 */
 	public AssetAdministrationShell() {
-		this(null, null, new Asset(), new HashSet<SubModel>(), new HashSet<IConceptDictionary>(), new HashSet<IView>());
+		this(null, null, new Asset(), new HashSet<Submodel>(), new HashSet<IConceptDictionary>(), new HashSet<IView>());
+	}
+	
+	/**
+	 * Constructor accepting only mandatory attributes
+	 * @param idShort
+	 * @param identification
+	 * @param asset
+	 */
+	public AssetAdministrationShell(String idShort, IIdentifier identification, Asset asset) {
+		this(null, null, asset, new HashSet<Submodel>(), new HashSet<IConceptDictionary>(), new HashSet<IView>());
+		setIdentification(identification);
+		setIdShort(idShort);
 	}
 
 	public AssetAdministrationShell(Reference derivedFrom, Security security, Asset asset,
-			Collection<SubModel> submodels, Collection<IConceptDictionary> dictionaries, Collection<IView> views) {
+			Collection<Submodel> submodels, Collection<IConceptDictionary> dictionaries, Collection<IView> views) {
 		// Add model type
 		putAll(new ModelType(MODELTYPE));
 		
@@ -85,7 +105,7 @@
 		setSecurity(security);
 		setDerivedFrom(derivedFrom);
 		setAsset(asset);
-		setSubModels(submodels);
+		setSubmodels(submodels);
 
 		setViews(views);
 		setConceptDictionary(dictionaries);
@@ -103,30 +123,30 @@
 		if (map == null) {
 			return null;
 		}
+		
+		if (!isValid(map)) {
+			throw new MetamodelConstructionException(AssetAdministrationShell.class, map);
+		}
+					
+		if (!map.containsKey(SUBMODELS)) {
+			map.put(SUBMODELS, new ArrayList<>());
+		}
 
 		AssetAdministrationShell ret = new AssetAdministrationShell();
 		ret.setMap(map);
-		return ret;
+		return ret;	
 	}
-
+	
 	/**
-	 * Sets the endpoint of the AAS
-	 * 
-	 * @param endpoint
-	 *            is expected to end with "/aas"
-	 * @param endpointType
+	 * Check whether all mandatory elements for the metamodel
+	 * exist in a map
+	 * @return true/false
 	 */
-	public void setEndpoint(String endpoint, String endpointType) {
-		HashMap<String, String> endpointWrapper = new HashMap<String, String>();
-		endpointWrapper.put(TYPE, endpointType);
-		endpointWrapper.put(ADDRESS, endpoint);
-
-		put(ENDPOINTS, Arrays.asList(endpointWrapper));
-	}
-
 	@SuppressWarnings("unchecked")
-	public List<HashMap<String, String>> getEndpoints() {
-		return (List<HashMap<String, String>>) get(ENDPOINTS);
+	public static boolean isValid(Map<String, Object> map) {
+		return Identifiable.isValid(map) &&
+				map.containsKey(AssetAdministrationShell.ASSET) &&
+				Asset.isValid((Map<String, Object>)map.get(AssetAdministrationShell.ASSET));
 	}
 
 	@Override
@@ -148,7 +168,7 @@
 	}
 
 	public void setIdentification(IdentifierType idType, String id) {
-		Identifiable.createAsFacade(this, getKeyElement()).setIdentification(idType, id);
+		Identifiable.createAsFacadeNonStrict(this, getKeyElement()).setIdentification(idType, id);
 	}
 
 	@Override
@@ -170,7 +190,7 @@
 	}
 
 	public void setIdShort(String id) {
-		Referable.createAsFacade(this, getKeyElement()).setIdShort(id);
+		Referable.createAsFacadeNonStrict(this, getKeyElement()).setIdShort(id);
 	}
 
 	public void setSecurity(ISecurity security) {
@@ -214,7 +234,7 @@
 	}
 
 	@SuppressWarnings("unchecked")
-	public void setSubModels(Collection<SubModel> submodels) {
+	public void setSubmodels(Collection<Submodel> submodels) {
 		setSubmodelParent(submodels);
 
 		// Clear submodel references and add new keys
@@ -246,8 +266,8 @@
 	}
 
 	@Override
-	public Map<String, ISubModel> getSubModels() {
-		throw new RuntimeException("getSubModels on local copy is not supported");
+	public Map<String, ISubmodel> getSubmodels() {
+		throw new RuntimeException("getSubmodels on local copy is not supported");
 	}
 
 	@Override
@@ -283,12 +303,19 @@
 	}
 
 	@Override
-	public void addSubModel(SubModel submodel) {
+	public void addSubmodel(Submodel submodel) {
 		logger.trace("adding Submodel", submodel.getIdentification().getId());
 		setSubmodelParent(Collections.singletonList(submodel));
 		addSubmodelReferences(submodel);
 	}
 
+
+	@Override
+	public void removeSubmodel(IIdentifier id) {
+		// Currently not implemented since future of Submodel References in AAS is not clear
+		throw new FeatureNotImplementedException();
+	}
+
 	/**
 	 * Allows addition of a concept description to the concept dictionary
 	 * 
@@ -298,7 +325,7 @@
 	public void addConceptDescription(IConceptDescription description) {
 		Collection<IConceptDictionary> dictionaries = (Collection<IConceptDictionary>) get(AssetAdministrationShell.CONCEPTDICTIONARY);
 		if (dictionaries.isEmpty()) {
-			dictionaries.add(new ConceptDictionary());
+			dictionaries.add(new ConceptDictionary("defaultConceptDictionary"));
 		}
 		ConceptDictionary dictionary = (ConceptDictionary) dictionaries.iterator().next();
 		dictionary.addConceptDescription(description);
@@ -319,22 +346,22 @@
 		smReferences.add(reference);
 	}
 
-	private void addSubmodelReferences(SubModel submodel) {
+	private void addSubmodelReferences(Submodel submodel) {
 		addSubmodelReference(submodel.getReference());
 	}
-	
+
 	private KeyElements getKeyElement() {
 		return KeyElements.ASSETADMINISTRATIONSHELL;
 	}
 	
 	/**
-	 * Set reference of current AAS to each SubModel of a collection
+	 * Set reference of current AAS to each Submodel of a collection
 	 * as a parent reference
 	 * 
 	 * @param submodels collection of Submodels
 	 */
-	private void setSubmodelParent(Collection<SubModel> submodels) {
-		for (SubModel submodel : submodels) {
+	private void setSubmodelParent(Collection<Submodel> submodels) {
+		for (Submodel submodel : submodels) {
 			submodel.setParent(getReference());
 		}
 	}
@@ -342,4 +369,10 @@
 	public IReference getReference() {
 		return Identifiable.createAsFacade(this, getKeyElement()).getReference();
 	}
+
+	@Override
+	public ISubmodel getSubmodel(IIdentifier id) {
+		throw new RuntimeException("getSubmodel on local copy is not supported");
+	}
+
 }
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/descriptor/AASDescriptor.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/descriptor/AASDescriptor.java
index cdd617e..ed3f8e1 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/descriptor/AASDescriptor.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/descriptor/AASDescriptor.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.aas.metamodel.map.descriptor;
 
 import java.util.Collection;
@@ -14,6 +23,7 @@
 import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
 import org.eclipse.basyx.submodel.metamodel.map.modeltype.ModelType;
 import org.eclipse.basyx.submodel.metamodel.map.qualifier.Identifiable;
+import org.eclipse.basyx.vab.exception.provider.MalformedRequestException;
 
 /**
  * AAS descriptor class
@@ -22,7 +32,7 @@
  *
  */
 public class AASDescriptor extends ModelDescriptor {
-	public static final String MODELTYPE = "AASDescriptor";
+	public static final String MODELTYPE = "AssetAdministrationShellDescriptor";
 	public static final String ASSET = "asset";
 	
 	/**
@@ -30,6 +40,10 @@
 	 */
 	public AASDescriptor(Map<String, Object> map) {
 		super(map);
+		validate(map);
+
+		// Set map again
+		putAll(map);
 	}
 
 	protected AASDescriptor() {
@@ -96,6 +110,7 @@
 		
 		// Add new sub model descriptor to list
 		submodelDescriptors.add(desc);
+		put(AssetAdministrationShell.SUBMODELS, submodelDescriptors);
 
 		// Enable method chaining
 		return this;
@@ -103,7 +118,18 @@
 
 	@SuppressWarnings("unchecked")
 	public void removeSubmodelDescriptor(String idShort) {
-		Optional<SubmodelDescriptor> toRemove = getSubModelDescriptors().stream().filter(x -> x.getIdShort().equals(idShort)).findAny();
+		Optional<SubmodelDescriptor> toRemove = getSubmodelDescriptors().stream().filter(x -> x.getIdShort().equals(idShort)).findAny();
+
+		// TODO: Exception in else case
+		if (toRemove.isPresent()) {
+			// Don't use getSubmodelDescriptors here since it returns a copy
+			((Collection<Object>) get(AssetAdministrationShell.SUBMODELS)).remove(toRemove.get());
+		}
+	}
+
+	@SuppressWarnings("unchecked")
+	public void removeSubmodelDescriptor(IIdentifier id) {
+		Optional<SubmodelDescriptor> toRemove = getSubmodelDescriptors().stream().filter(x -> x.getIdentifier().getId().equals(id.getId())).findAny();
 
 		// TODO: Exception in else case
 		if (toRemove.isPresent()) {
@@ -120,7 +146,7 @@
 	 * @return
 	 */
 	@SuppressWarnings("unchecked")
-	public SubmodelDescriptor getSubModelDescriptorFromIdentifierId(String subModelId) {
+	public SubmodelDescriptor getSubmodelDescriptorFromIdentifierId(String subModelId) {
 		// Sub model descriptors are stored in a list
 		Collection<Map<String, Object>> smDescriptorMaps = (Collection<Map<String, Object>>) get(
 				AssetAdministrationShell.SUBMODELS);
@@ -145,14 +171,14 @@
 	 * @return
 	 */
 	public SubmodelDescriptor getSubmodelDescriptorFromIdShort(String idShort) {
-		return getSubModelDescriptors().stream().filter(x -> x.getIdShort().equals(idShort)).findAny().orElse(null); // TODO: Exception
+		return getSubmodelDescriptors().stream().filter(x -> x.getIdShort().equals(idShort)).findAny().orElse(null); // TODO: Exception
 	}
 
 	/**
 	 * Get a specific sub model descriptor from a ModelUrn
 	 */
-	public SubmodelDescriptor getSubModelDescriptor(ModelUrn submodelUrn) {
-		return getSubModelDescriptorFromIdentifierId(submodelUrn.getURN());
+	public SubmodelDescriptor getSubmodelDescriptor(ModelUrn submodelUrn) {
+		return getSubmodelDescriptorFromIdentifierId(submodelUrn.getURN());
 	}
 
 	/**
@@ -161,7 +187,7 @@
 	 * @return
 	 */
 	@SuppressWarnings("unchecked")
-	public Collection<SubmodelDescriptor> getSubModelDescriptors() {
+	public Collection<SubmodelDescriptor> getSubmodelDescriptors() {
 		Collection<Map<String, Object>> descriptors = (Collection<Map<String, Object>>) get(AssetAdministrationShell.SUBMODELS);
 		return descriptors.stream().map(SubmodelDescriptor::new).collect(Collectors.toSet());
 	}
@@ -179,5 +205,15 @@
 		Map<String, Object> assetModel = (Map<String, Object>) get(ASSET);
 		return Asset.createAsFacade(assetModel);
 	}
+	
+	@Override
+	public void validate(Map<String, Object> map) {
+		super.validate(map);
+		if (!map.containsKey(AssetAdministrationShell.SUBMODELS)) {
+			map.put(AssetAdministrationShell.SUBMODELS, new HashSet<>());
+		} else if (map.containsKey(AssetAdministrationShell.SUBMODELS) && !(map.get(AssetAdministrationShell.SUBMODELS) instanceof Collection<?>)) {
+			throw new MalformedRequestException("Passed entry for " + AssetAdministrationShell.SUBMODELS + " is not a list of submodelDescriptors!");
+		}
+	}
 }
 
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/descriptor/CustomId.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/descriptor/CustomId.java
new file mode 100644
index 0000000..7c0b29e
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/descriptor/CustomId.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.aas.metamodel.map.descriptor;
+
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+
+/**
+ * CustomId identifier
+ * 
+ * @author schnicke
+ *
+ */
+public class CustomId extends Identifier {
+
+	/**
+	 * Creates a new Identifier with IdentifierType == IdentifierType.CUSTOM
+	 * 
+	 * @param id
+	 */
+	public CustomId(String id) {
+		super(IdentifierType.CUSTOM, id);
+	}
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/descriptor/ModelDescriptor.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/descriptor/ModelDescriptor.java
index ed3e562..8dc0b62 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/descriptor/ModelDescriptor.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/descriptor/ModelDescriptor.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.aas.metamodel.map.descriptor;
 
 import java.util.ArrayList;
@@ -12,6 +21,7 @@
 import org.eclipse.basyx.submodel.metamodel.map.modeltype.ModelType;
 import org.eclipse.basyx.submodel.metamodel.map.qualifier.Identifiable;
 import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
+import org.eclipse.basyx.vab.exception.provider.MalformedRequestException;
 import org.eclipse.basyx.vab.model.VABModelMap;
 
 /**
@@ -24,6 +34,7 @@
  *
  */
 public abstract class ModelDescriptor extends VABModelMap<Object> {
+	public static final String ENDPOINTS = "endpoints";
 
 	protected ModelDescriptor() {
 		putAll(new ModelType(getModelType()));
@@ -55,7 +66,7 @@
 		HashMap<String, String> endpointWrapper = new HashMap<>();
 		endpointWrapper.put(AssetAdministrationShell.TYPE, "http");
 		endpointWrapper.put(AssetAdministrationShell.ADDRESS, httpEndpoint);
-		put(AssetAdministrationShell.ENDPOINTS, Arrays.asList(endpointWrapper));
+		put(ENDPOINTS, Arrays.asList(endpointWrapper));
 	}
 
 	/**
@@ -77,7 +88,7 @@
 	 */
 	@SuppressWarnings("unchecked")
 	public String getFirstEndpoint() {
-		Object e = get(AssetAdministrationShell.ENDPOINTS);
+		Object e = get(ENDPOINTS);
 		// Extract String from endpoint for set or list representations of the endpoint wrappers
 		if (e instanceof Collection<?>) {
 			Collection<Map<?, ?>> endpoints = (Collection<Map<?, ?>>) e;
@@ -97,7 +108,7 @@
 	 */
 	@SuppressWarnings("unchecked")
 	public Collection<Map<String, Object>> getEndpoints() {
-		Object endpoints = get(AssetAdministrationShell.ENDPOINTS);
+		Object endpoints = get(ENDPOINTS);
 		// Extract String from endpoint for set or list representations of the endpoint wrappers
 		if (endpoints instanceof Collection<?>) {
 			return (Collection<Map<String, Object>>) endpoints;
@@ -105,6 +116,20 @@
 			return new ArrayList<>();
 		}
 	}
+	
+	/**
+	 * Validates a model descriptor by checking whether
+	 * idShort, identification and endpoints key is present in the given map
+	 * @param map
+	 */
+	protected void validate(Map<String, Object> map) {
+		if (!map.containsKey(Referable.IDSHORT) || !(map.get(Referable.IDSHORT) instanceof String)) 
+			throw new MalformedRequestException(getModelType() + " is missing idShort entry");
+		if (!map.containsKey(Identifiable.IDENTIFICATION) || !(map.get(Identifiable.IDENTIFICATION) instanceof Map<?, ?>))
+			throw new MalformedRequestException(getModelType() + " is missing identification entry");
+		if (!map.containsKey(ENDPOINTS) || !(map.get(ENDPOINTS) instanceof Collection<?>))
+			throw new MalformedRequestException(getModelType() + " is missing endpoints entry");
+	}
 
 	protected abstract String getModelType();
 }
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/descriptor/ModelUrn.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/descriptor/ModelUrn.java
index a89bc23..81f0433 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/descriptor/ModelUrn.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/descriptor/ModelUrn.java
@@ -1,10 +1,19 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.aas.metamodel.map.descriptor;
 
 import java.io.UnsupportedEncodingException;
 import java.net.URLEncoder;
 
-import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
 import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -14,23 +23,20 @@
  * @author kuhn
  *
  */
-public class ModelUrn implements IIdentifier {
+public class ModelUrn extends Identifier {
 
 	private static Logger logger = LoggerFactory.getLogger(ModelUrn.class);
 
-	
-	/**
-	 * URN string
-	 */
-	protected String urnString = null;
-	
-	
+	private ModelUrn() {
+		setIdType(IdentifierType.IRI);
+	}
 	
 	/**
 	 * Constructor that accepts a single, raw URN
 	 */
 	public ModelUrn(String rawURN) {
-		urnString = rawURN;
+		this();
+		setId(rawURN);
 	}
 	
 	
@@ -38,6 +44,7 @@
 	 * Constructor that build a URN
 	 */
 	public ModelUrn(String legalEntity, String subUnit, String subModel, String version, String revision, String elementId, String elementInstance) {
+		this();
 		// Goal is: urn:<legalEntity>:<subUnit>:<subModel>:<version>:<revision>:<elementID>#<elementInstance>
 		StringBuffer urnBuilder = new StringBuffer();
 		
@@ -54,7 +61,7 @@
 		if (elementInstance != null) urnBuilder.append("#"+elementInstance);
 		
 		// Build URN
-		urnString = urnBuilder.toString();
+		setId(urnBuilder.toString());
 	}
 	
 	
@@ -63,7 +70,7 @@
 	 * Get URN as string
 	 */
 	public String getURN() {
-		return urnString;
+		return getId();
 	}
 	
 	
@@ -73,7 +80,7 @@
 	public String getEncodedURN() {
 		try {
 			// Try to encode urn string
-			return URLEncoder.encode(urnString, "UTF-8");
+			return URLEncoder.encode(getId(), "UTF-8");
 		} catch (UnsupportedEncodingException e) {
 			// Catch block
 			logger.error("Exception in getEncodedURN", e);
@@ -86,44 +93,7 @@
 	 */
 	public ModelUrn append(String suffix) {
 		// Append suffix
-		return new ModelUrn(urnString + suffix);
-	}
-	
-	/**
-	 * A ModelUrn is a unique identifier and is a specialization of an URI
-	 */
-	@Override
-	public IdentifierType getIdType() {
-		return IdentifierType.IRI;
-	}
-
-	/**
-	 * A ModelUrn is a unique identifier => the urn is the id
-	 */
-	@Override
-	public String getId() {
-		return getURN();
-	}
-	
-	/**
-	 * HashCode method - required to be able to use this class as hashmap key
-	 */
-	@Override
-	public int hashCode() {
-		return urnString.hashCode();
-	}
-	
-	
-	/**
-	 * Check equality - required to be able to use this class as hashmap key
-	 */
-	@Override
-	public boolean equals(Object obj) {
-		// Type check
-		if (!(obj instanceof ModelUrn)) return false;
-		
-		// Check values
-		return urnString.equals(((ModelUrn) obj).urnString);
+		return new ModelUrn(getId() + suffix);
 	}
 }
 
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/descriptor/SubmodelDescriptor.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/descriptor/SubmodelDescriptor.java
index 2149eda..2ccb817 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/descriptor/SubmodelDescriptor.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/descriptor/SubmodelDescriptor.java
@@ -1,11 +1,23 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.aas.metamodel.map.descriptor;
 
 import java.util.Map;
 
-import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
 import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.submodel.metamodel.api.qualifier.IHasSemantics;
+import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
 import org.eclipse.basyx.submodel.metamodel.map.modeltype.ModelType;
 import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasSemantics;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
 
 
 
@@ -16,7 +28,7 @@
  * @author kuhn
  *
  */
-public class SubmodelDescriptor extends ModelDescriptor {
+public class SubmodelDescriptor extends ModelDescriptor implements IHasSemantics {
 	
 	public static final String MODELTYPE = "SubmodelDescriptor";
 
@@ -25,13 +37,14 @@
 	 */
 	public SubmodelDescriptor(Map<String, Object> map) {
 		super(map);
+		validate(map);
 	}
 	
 	/**
 	 * Create a new aas descriptor with minimal information based on an existing
 	 * submodel.
 	 */
-	public SubmodelDescriptor(ISubModel sm, String httpEndpoint) {
+	public SubmodelDescriptor(ISubmodel sm, String httpEndpoint) {
 		// Create descriptor with minimal information (id and idShort)
 		this(sm.getIdShort(), sm.getIdentification(), httpEndpoint);
 		
@@ -42,7 +55,7 @@
 	 * Create a new descriptor with minimal information
 	 */
 	public SubmodelDescriptor(String idShort, IIdentifier id, String httpEndpoint) {
-		super(idShort, id, httpEndpoint);
+		super(idShort, id, harmonizeEndpoint(httpEndpoint));
 		
 		// Add model type
 		putAll(new ModelType(MODELTYPE));
@@ -52,5 +65,23 @@
 	protected String getModelType() {
 		return MODELTYPE;
 	}
+
+	private static String harmonizeEndpoint(String endpoint) {
+		if (!endpoint.endsWith("/submodel")) {
+			return endpoint + "/submodel";
+		} else {
+			return endpoint;
+		}
+	}
+
+	@Override
+	public IReference getSemanticId() {
+		return HasSemantics.createAsFacade(this).getSemanticId();
+	}
+
+	public void setSemanticId(Reference ref) {
+		HasSemantics.createAsFacade(this).setSemanticId(ref);
+	}
+
 }
 
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/parts/Asset.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/parts/Asset.java
index 6c2f8d5..c62365b 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/parts/Asset.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/parts/Asset.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.aas.metamodel.map.parts;
 
 import java.util.Collection;
@@ -5,6 +14,7 @@
 
 import org.eclipse.basyx.aas.metamodel.api.parts.asset.AssetKind;
 import org.eclipse.basyx.aas.metamodel.api.parts.asset.IAsset;
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
 import org.eclipse.basyx.submodel.metamodel.api.dataspecification.IEmbeddedDataSpecification;
 import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
 import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
@@ -49,8 +59,20 @@
 		putAll(new Identifiable());
 
 		// Default values
-		put(ASSETIDENTIFICATIONMODEL, null);
-		put(KIND, null);
+		setAssetKind(AssetKind.INSTANCE);
+	}
+	
+	/**
+	 * Constructor accepting only mandatory attributes
+	 * @param idShort
+	 * @param identification
+	 * @param kind
+	 */
+	public Asset(String idShort, IIdentifier identification, AssetKind kind) {
+		this();
+		setIdentification(identification);
+		setIdShort(idShort);
+		setAssetKind(kind);
 	}
 
 	/**
@@ -76,10 +98,25 @@
 		if (map == null) {
 			return null;
 		}
+		
+		if (!isValid(map)) {
+			throw new MetamodelConstructionException(Asset.class, map);
+		}
+		
 		Asset ret = new Asset();
 		ret.setMap(map);
 		return ret;
 	}
+	
+	/**
+	 * Check whether all mandatory elements for the metamodel
+	 * exist in a map
+	 * @return true/false
+	 */
+	public static boolean isValid(Map<String, Object> map) {
+		return Identifiable.isValid(map) && 
+				map.containsKey(Asset.KIND);
+	}
 
 	@Override
 	public Collection<IReference> getDataSpecificationReferences() {
@@ -122,8 +159,12 @@
 		Identifiable.createAsFacade(this, getKeyElement()).setAdministration(information);
 	}
 
+	public void setIdentification(IIdentifier id) {
+		setIdentification(id.getIdType(), id.getId());
+	}
+
 	public void setIdentification(IdentifierType idType, String id) {
-		Identifiable.createAsFacade(this, getKeyElement()).setIdentification(idType, id);
+		Identifiable.createAsFacadeNonStrict(this, getKeyElement()).setIdentification(idType, id);
 	}
 
 	@Override
@@ -156,7 +197,7 @@
 	}
 
 	public void setIdShort(String idShort) {
-		Referable.createAsFacade(this, getKeyElement()).setIdShort(idShort);
+		Referable.createAsFacadeNonStrict(this, getKeyElement()).setIdShort(idShort);
 	}
 
 	public void setCategory(String category) {
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/parts/ConceptDictionary.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/parts/ConceptDictionary.java
index 53e3ed5..b418b99 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/parts/ConceptDictionary.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/parts/ConceptDictionary.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.aas.metamodel.map.parts;
 
 import java.util.ArrayList;
@@ -5,6 +14,7 @@
 import java.util.Map;
 
 import org.eclipse.basyx.aas.metamodel.api.parts.IConceptDictionary;
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
 import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
 import org.eclipse.basyx.submodel.metamodel.api.parts.IConceptDescription;
 import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
@@ -32,10 +42,18 @@
 	 * Constructor
 	 */
 	public ConceptDictionary() {
-		putAll(new Referable());
 		put(CONCEPTDESCRIPTION, new ArrayList<IReference>());
 		put(CONCEPTDESCRIPTIONS, new ArrayList<IConceptDescription>());
 	}
+	
+	/**
+	 * Constructor accepting only mandatory attribute
+	 * @param idShort
+	 */
+	public ConceptDictionary(String idShort) {
+		this();
+		setIdShort(idShort);
+	}
 
 	public ConceptDictionary(Collection<IReference> ref) {
 		putAll(new Referable());
@@ -55,11 +73,24 @@
 		if (map == null) {
 			return null;
 		}
-
+		
+		if (!isValid(map)) {
+			throw new MetamodelConstructionException(ConceptDictionary.class, map);
+		}
+		
 		ConceptDictionary ret = new ConceptDictionary();
 		ret.setMap(map);
 		return ret;
 	}
+	
+	/**
+	 * Check whether all mandatory elements for the metamodel
+	 * exist in a map
+	 * @return true/false
+	 */
+	public static boolean isValid(Map<String, Object> map) {
+		return Referable.isValid(map);
+	}
 
 	@Override
 	public String getIdShort() {
@@ -82,7 +113,7 @@
 	}
 
 	public void setIdShort(String idShort) {
-		Referable.createAsFacade(this, getKeyElement()).setIdShort(idShort);
+		Referable.createAsFacadeNonStrict(this, getKeyElement()).setIdShort(idShort);
 	}
 
 	public void setCategory(String category) {
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/parts/View.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/parts/View.java
index 7bb740a..8b80b01 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/parts/View.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/parts/View.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.aas.metamodel.map.parts;
 
 import java.util.Collection;
@@ -6,6 +15,7 @@
 import java.util.Set;
 
 import org.eclipse.basyx.aas.metamodel.api.parts.IView;
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
 import org.eclipse.basyx.submodel.metamodel.api.dataspecification.IEmbeddedDataSpecification;
 import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
 import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
@@ -38,13 +48,20 @@
 		putAll(new ModelType(MODELTYPE));
 
 		// Add qualifiers
-		putAll(new HasSemantics());
 		putAll(new HasDataSpecification());
-		putAll(new Referable());
 
 		// Default values
 		put(CONTAINEDELEMENT, new HashSet<Reference>());
 	}
+	
+	/**
+	 * Constructor accepting only mandatory attribute
+	 * @param idShort
+	 */
+	public View(String idShort) {
+		this();
+		setIdShort(idShort);
+	}
 
 	/**
 	 * 
@@ -67,11 +84,24 @@
 		if (map == null) {
 			return null;
 		}
-
+		
+		if (!isValid(map)) {
+			throw new MetamodelConstructionException(View.class, map);
+		}
+		
 		View ret = new View();
 		ret.setMap(map);
 		return ret;
 	}
+	
+	/**
+	 * Check whether all mandatory elements for the metamodel
+	 * exist in a map
+	 * @return true/false
+	 */
+	public static boolean isValid(Map<String, Object> map) {
+		return Referable.isValid(map);
+	}
 
 	public void setContainedElement(Collection<IReference> references) {
 		put(View.CONTAINEDELEMENT, references);
@@ -88,7 +118,7 @@
 	}
 
 	public void setSemanticId(IReference ref) {
-		HasSemantics.createAsFacade(this).setSemanticID(ref);
+		HasSemantics.createAsFacade(this).setSemanticId(ref);
 
 	}
 
@@ -131,7 +161,7 @@
 	}
 
 	public void setIdShort(String idShort) {
-		Referable.createAsFacade(this, getKeyElement()).setIdShort(idShort);
+		Referable.createAsFacadeNonStrict(this, getKeyElement()).setIdShort(idShort);
 	}
 
 	public void setCategory(String category) {
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/policypoints/AccessControlPolicyPoints.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/policypoints/AccessControlPolicyPoints.java
index ec0480b..30e71fe 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/policypoints/AccessControlPolicyPoints.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/policypoints/AccessControlPolicyPoints.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.aas.metamodel.map.policypoints;
 
 import java.util.Map;
@@ -20,14 +29,7 @@
 	/**
 	 * Constructor
 	 */
-	public AccessControlPolicyPoints() {
-		// Default values
-		put(POLICYADMINISTRATIONPOINT, null);
-		put(POLICYDECISIONPOINT, null);
-		put(POLICYENFORECEMENTPOINT, null);
-
-		put(POLICYINFORMATIONPOINTS, null);
-	}
+	public AccessControlPolicyPoints() {}
 
 	/**
 	 * Creates a DataSpecificationIEC61360 object from a map
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/policypoints/PolicyAdministrationPoint.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/policypoints/PolicyAdministrationPoint.java
index bbe2f24..8495d8b 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/policypoints/PolicyAdministrationPoint.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/policypoints/PolicyAdministrationPoint.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.aas.metamodel.map.policypoints;
 
 /**
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/policypoints/PolicyDecisionPoint.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/policypoints/PolicyDecisionPoint.java
index 33a8994..824f657 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/policypoints/PolicyDecisionPoint.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/policypoints/PolicyDecisionPoint.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.aas.metamodel.map.policypoints;
 
 /**
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/policypoints/PolicyEnforcementPoint.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/policypoints/PolicyEnforcementPoint.java
index eaacae3..158c7b9 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/policypoints/PolicyEnforcementPoint.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/policypoints/PolicyEnforcementPoint.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.aas.metamodel.map.policypoints;
 
 /**
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/policypoints/PolicyInformationPoints.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/policypoints/PolicyInformationPoints.java
index 19dcd5b..908ff56 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/policypoints/PolicyInformationPoints.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/policypoints/PolicyInformationPoints.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.aas.metamodel.map.policypoints;
 
 /**
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/security/Security.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/security/Security.java
index 01feb38..32ff7f9 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/security/Security.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/security/Security.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.aas.metamodel.map.security;
 
 import java.util.Map;
@@ -23,11 +32,7 @@
 	/**
 	 * Constructor
 	 */
-	public Security() {
-		// Default values
-		put(ACCESSCONTROLPOLICYPOINTS, null);
-		put(CERTIFICATE, null);
-	}
+	public Security() {}
 
 	/**
 	 * Creates a Security object from a map
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/api/IAASRegistry.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/api/IAASRegistry.java
new file mode 100644
index 0000000..2173b06
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/api/IAASRegistry.java
@@ -0,0 +1,85 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.aas.registration.api;
+
+import java.util.List;
+
+import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.vab.exception.provider.ProviderException;
+
+
+
+
+/**
+ * BaSys registry interface
+ * 
+ * @author kuhn
+ *
+ */
+public interface IAASRegistry {
+	
+	/**
+	 * Register AAS descriptor in registry, delete old registration 
+	 */
+	public void register(AASDescriptor deviceAASDescriptor) throws ProviderException;
+
+	/**
+	 * Register SM descriptor in registry, delete old registration
+	 */
+	public void register(IIdentifier aas, SubmodelDescriptor smDescriptor) throws ProviderException;
+
+	/**
+	 * Delete AAS descriptor from registry
+	 */
+	public void delete(IIdentifier aasId) throws ProviderException;
+	
+	/**
+	 * Delete SM descriptor from registry
+	 */
+	public void delete(IIdentifier aasId, IIdentifier smId) throws ProviderException;
+	
+	/**
+	 * Lookup AAS
+	 */
+	public AASDescriptor lookupAAS(IIdentifier aasId) throws ProviderException;
+
+	/**
+	 * Retrieve all registered AAS
+	 * 
+	 * @return
+	 */
+	public List<AASDescriptor> lookupAll() throws ProviderException;
+
+	/**
+	 * Retrieves all SubmodelDescriptors of submodels of an AAS
+	 * 
+	 * @param aasId
+	 *            of the AAS
+	 * @return list of SubmodelDescriptors
+	 * @throws ProviderException
+	 */
+	public List<SubmodelDescriptor> lookupSubmodels(IIdentifier aasId) throws ProviderException;
+
+	/**
+	 * Retrieves the SubmodelDescriptor of a specific submodel of an AAS
+	 * 
+	 * @param aasId
+	 *            of the AAS
+	 * @param smId
+	 *            of the Submodel
+	 * @return the SubmodelDescriptor
+	 * @throws ProviderException
+	 */
+	public SubmodelDescriptor lookupSubmodel(IIdentifier aasId, IIdentifier smId) throws ProviderException;
+
+}
+
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/api/IAASRegistryService.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/api/IAASRegistryService.java
deleted file mode 100644
index 2dc8ede..0000000
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/api/IAASRegistryService.java
+++ /dev/null
@@ -1,53 +0,0 @@
-package org.eclipse.basyx.aas.registration.api;
-
-import java.util.List;
-
-import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
-import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
-import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
-import org.eclipse.basyx.vab.exception.provider.ProviderException;
-
-
-
-
-/**
- * BaSys registry interface
- * 
- * @author kuhn
- *
- */
-public interface IAASRegistryService {
-	
-	/**
-	 * Register AAS descriptor in registry, delete old registration 
-	 */
-	public void register(AASDescriptor deviceAASDescriptor) throws ProviderException;
-
-	/**
-	 * Register SM descriptor in registry, delete old registration
-	 */
-	public void register(IIdentifier aas, SubmodelDescriptor smDescriptor) throws ProviderException;
-
-	/**
-	 * Delete AAS descriptor from registry
-	 */
-	public void delete(IIdentifier aasId) throws ProviderException;
-	
-	/**
-	 * Delete SM descriptor from registry
-	 */
-	public void delete(IIdentifier aasId, String smIdShort) throws ProviderException;
-	
-	/**
-	 * Lookup AAS
-	 */
-	public AASDescriptor lookupAAS(IIdentifier aasId) throws ProviderException;
-
-	/**
-	 * Retrieve all registered AAS
-	 * 
-	 * @return
-	 */
-	public List<AASDescriptor> lookupAll() throws ProviderException;
-}
-
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/memory/AASRegistry.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/memory/AASRegistry.java
new file mode 100644
index 0000000..021d654
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/memory/AASRegistry.java
@@ -0,0 +1,133 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.aas.registration.memory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.vab.exception.provider.ProviderException;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Implements a generic AAS registry that makes use of a given handler.
+ */
+public class AASRegistry implements IAASRegistry {
+	private static Logger logger = LoggerFactory.getLogger(AASRegistry.class);
+	protected IRegistryHandler handler;
+	
+	public AASRegistry(IRegistryHandler handler) {
+		this.handler = handler;
+	}
+
+	@Override
+	public void register(AASDescriptor aasDescriptor) {
+		IIdentifier aasIdentifier = aasDescriptor.getIdentifier();
+		if (handler.contains(aasIdentifier)) {
+			handler.update(aasDescriptor);
+		} else {
+			handler.insert(aasDescriptor);
+		}
+		logger.debug("Registered " + aasIdentifier.getId());
+	}
+
+	@Override
+	public void delete(IIdentifier aasIdentifier) {
+		String aasId = aasIdentifier.getId();
+		if (!handler.contains(aasIdentifier)) {
+			throw new ResourceNotFoundException(
+					"Could not delete key for AAS " + aasId + " since it does not exist");
+		} else {
+			handler.remove(aasIdentifier);
+			logger.debug("Removed " + aasId);
+		}
+	}
+
+	@Override
+	public AASDescriptor lookupAAS(IIdentifier aasIdentifier) {
+		String aasId = aasIdentifier.getId();
+		if (!handler.contains(aasIdentifier)) {
+			throw new ResourceNotFoundException(
+					"Could not look up descriptor for AAS " + aasId + " since it does not exist");
+		}
+		return handler.get(aasIdentifier);
+	}
+
+	@Override
+	public List<AASDescriptor> lookupAll() {
+		logger.debug("Looking up all AAS");
+		return handler.getAll();
+	}
+
+	@Override
+	public void register(IIdentifier aas, SubmodelDescriptor smDescriptor) {
+		try {
+			delete(aas, smDescriptor.getIdentifier());
+		} catch (ResourceNotFoundException e) {
+			// Doesn't matter
+		}
+
+		AASDescriptor descriptor = handler.get(aas);
+		if(descriptor == null) {
+			throw new ResourceNotFoundException(
+					"Could not add submodel descriptor for AAS " + aas.getId() + " since the AAS does not exist");
+		}
+		
+		descriptor.addSubmodelDescriptor(smDescriptor);
+		handler.update(descriptor);
+		logger.debug("Registered submodel " + smDescriptor.getIdShort() + " for AAS " + aas.getId());
+	}
+
+	@Override
+	public void delete(IIdentifier aasId, IIdentifier smId) {
+		String smIdString = smId.getId();
+		AASDescriptor desc = handler.get(aasId);
+		if (desc == null) {
+			throw new ResourceNotFoundException(
+					"Could not delete submodel descriptor for AAS " + aasId.getId() + " since the AAS does not exist");
+		}
+		if (desc.getSubmodelDescriptorFromIdentifierId(smIdString) == null) {
+			throw new ResourceNotFoundException(
+					"Could not delete submodel descriptor for AAS " + aasId.getId() + " since the SM does not exist");
+		}
+
+		desc.removeSubmodelDescriptor(smId);
+		handler.update(desc);
+		logger.debug("Deleted submodel " + smIdString + " from AAS " + aasId.getId());
+	}
+
+	@Override
+	public List<SubmodelDescriptor> lookupSubmodels(IIdentifier aasId) throws ProviderException {
+		AASDescriptor desc = handler.get(aasId);
+		if (desc == null) {
+			throw new ResourceNotFoundException("Could not look up submodels for AAS " + aasId + " since it does not exist");
+		}
+
+		return new ArrayList<>(desc.getSubmodelDescriptors());
+	}
+
+	@Override
+	public SubmodelDescriptor lookupSubmodel(IIdentifier aasId, IIdentifier smId) throws ProviderException {
+		AASDescriptor desc = handler.get(aasId);
+		if (desc == null) {
+			throw new ResourceNotFoundException("Could not look up descriptor for SM " + smId + " of AAS " + aasId + " since the AAS does not exist");
+		}
+		SubmodelDescriptor smDesc = desc.getSubmodelDescriptorFromIdentifierId(smId.getId());
+		if (smDesc == null) {
+			throw new ResourceNotFoundException("Could not look up descriptor for SM " + smId + " of AAS " + aasId + " since the SM does not exist");
+		}
+		return smDesc;
+	}
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/memory/IRegistryHandler.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/memory/IRegistryHandler.java
new file mode 100644
index 0000000..d0c723f
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/memory/IRegistryHandler.java
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.aas.registration.memory;
+
+import java.util.List;
+
+import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+
+/**
+ * An interface for a registry handler for different types of registry datasources.
+ * 
+ * @author espen
+ *
+ */
+public interface IRegistryHandler {
+	/**
+	 * Queries the registry datasource to check, if an entry with the given identifier exists.
+	 * 
+	 * @param id The asset- or AAS-identifier that will be checked
+	 * @return True, if an entry with the given identifier exists
+	 */
+	public boolean contains(IIdentifier id);
+
+	/**
+	 * Removes an entry with a given identifier from the registry datasource
+	 * 
+	 * @param id The asset- or AAS-identifier that will be removed
+	 */
+	public void remove(IIdentifier id);
+
+	/**
+	 * Inserts a new descriptor into the registry datasource.
+	 * 
+	 * @param descriptor The descriptor that will be inserted.
+	 */
+	public void insert(AASDescriptor descriptor);
+
+	/**
+	 * Updates a given descriptor. It is assumed that an entry with the same AAS id already exists in the registry
+	 * datasource.
+	 * 
+	 * @param descriptor The descriptor that will be inserted.
+	 */
+	public void update(AASDescriptor descriptor);
+
+	/**
+	 * Queries the registry datasource for a entry with the given identifier.
+	 * 
+	 * @param id The asset- or AAS-identifier for which the descriptor should be retrieved.
+	 * @return The found descriptor from the registry datasource matching the id.
+	 */
+	public AASDescriptor get(IIdentifier id);
+
+	/**
+	 * Returns a list of all descriptors contained in the registry datasource.
+	 * 
+	 * @return The list of AASDescriptors.
+	 */
+	public List<AASDescriptor> getAll();
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/memory/InMemoryRegistry.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/memory/InMemoryRegistry.java
index 54c5046..a1d5625 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/memory/InMemoryRegistry.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/memory/InMemoryRegistry.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.aas.registration.memory;
 
 import java.util.HashMap;
@@ -9,12 +18,12 @@
  * @author espen
  *
  */
-public class InMemoryRegistry extends MapRegistry {
+public class InMemoryRegistry extends AASRegistry {
 
 	/**
 	 * Default constructor based on HashMaps
 	 */
 	public InMemoryRegistry() {
-		super(new HashMap<>());
+		super(new MapRegistryHandler(new HashMap<>()));
 	}
 }
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/memory/MapRegistry.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/memory/MapRegistry.java
deleted file mode 100644
index cccea83..0000000
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/memory/MapRegistry.java
+++ /dev/null
@@ -1,132 +0,0 @@
-package org.eclipse.basyx.aas.registration.memory;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-
-import org.eclipse.basyx.aas.metamodel.api.parts.asset.IAsset;
-import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
-import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
-import org.eclipse.basyx.aas.registration.api.IAASRegistryService;
-import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
-import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Implements a preconfigured registry based on the Map interface
- */
-public class MapRegistry implements IAASRegistryService {
-	protected Map<String, AASDescriptor> descriptorMap;
-
-	Logger logger = LoggerFactory.getLogger(MapRegistry.class);
-
-	/**
-	 * Constructor that takes a reference to a map as a base for the registry
-	 * entries
-	 */
-	public MapRegistry(Map<String, AASDescriptor> rootMap) {
-		descriptorMap = rootMap;
-	}
-
-	@Override
-	public void register(AASDescriptor aasDescriptor) {
-		String aasId = aasDescriptor.getIdentifier().getId();
-
-		// Get the Asset identifier from the descriptor
-		IAsset asset = aasDescriptor.getAsset();
-
-		if (descriptorMap.containsKey(aasId)) {
-			descriptorMap.remove(aasId);
-		}
-
-		// If asset identifier exists, delete the existing mapping,
-		// and add the new mapping
-		if (asset != null) {
-			IIdentifier assetIdentifier = asset.getIdentification();
-			if (descriptorMap.containsKey(assetIdentifier.getId())) {
-				descriptorMap.remove(assetIdentifier.getId());
-			}
-			descriptorMap.put(assetIdentifier.getId(), aasDescriptor);
-		}
-
-
-		descriptorMap.put(aasId, aasDescriptor);
-		logger.debug("Registered " + aasId);
-	}
-
-	@Override
-	public void delete(IIdentifier aasIdentifier) {
-		String aasId = aasIdentifier.getId();
-		if (!descriptorMap.containsKey(aasId)) {
-			throw new ResourceNotFoundException("Could not delete key for AAS " + aasId + " since it does not exist");
-		} else {
-			AASDescriptor aasDescriptor = lookupAAS(aasIdentifier);
-			descriptorMap.remove(aasId);
-
-			// Get the identifier of the asset
-			IAsset asset = aasDescriptor.getAsset();
-			// Delete the Mapping of asset-id to the AAS if exists
-			if (asset != null) {
-				descriptorMap.remove(asset.getIdentification().getId());
-			}
-
-			logger.debug("Removed " + aasId);
-		}
-	}
-
-	@Override
-	public AASDescriptor lookupAAS(IIdentifier aasIdentifier) {
-		String aasId = aasIdentifier.getId();
-		if (!descriptorMap.containsKey(aasId)) {
-			throw new ResourceNotFoundException("Could not look up descriptor for AAS " + aasId + " since it does not exist");
-		}
-		return descriptorMap.get(aasIdentifier.getId());
-	}
-
-
-	@Override
-	public List<AASDescriptor> lookupAll() {
-		logger.debug("Looking up all AAS");
-		// duplicate entries should be filtered
-		return new ArrayList<>(new HashSet<>(descriptorMap.values()));
-	}
-
-	@Override
-	public void register(IIdentifier aas, SubmodelDescriptor smDescriptor) {
-
-
-		try {
-			delete(aas, smDescriptor.getIdShort());
-		} catch (ResourceNotFoundException e) {
-			// Doesn't matter
-		}
-
-		AASDescriptor descriptor = descriptorMap.get(aas.getId());
-		descriptor.addSubmodelDescriptor(smDescriptor);
-		// Do not assume that the returned descriptor is referenced in the base map
-		descriptorMap.put(aas.getId(), descriptor);
-		logger.debug("Registered submodel " + smDescriptor.getIdShort() + " for AAS " + aas.getId());
-	}
-
-	@Override
-	public void delete(IIdentifier aasId, String smIdShort) {
-		AASDescriptor desc = descriptorMap.get(aasId.getId());
-		if (desc == null) {
-			throw new ResourceNotFoundException("Could not delete submodel descriptor for AAS " + aasId + " since the AAS does not exist");
-		}
-
-		if (desc.getSubmodelDescriptorFromIdShort(smIdShort) == null) {
-			throw new ResourceNotFoundException("Could not delete submodel descriptor for AAS " + aasId + " since the SM does not exist");
-		}
-
-		desc.removeSubmodelDescriptor(smIdShort);
-		// Do not assume that the returned descriptor is referenced in the base map
-		descriptorMap.put(aasId.getId(), desc);
-
-		logger.debug("Deleted submodel " + smIdShort + " from AAS " + aasId.getId());
-
-	}
-
-}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/memory/MapRegistryHandler.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/memory/MapRegistryHandler.java
new file mode 100644
index 0000000..cccb80b
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/memory/MapRegistryHandler.java
@@ -0,0 +1,85 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.aas.registration.memory;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.api.parts.asset.IAsset;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+
+/**
+ * Implements a preconfigured registry based on the Map interface
+ */
+public class MapRegistryHandler implements IRegistryHandler {
+	protected Map<String, AASDescriptor> descriptorMap;
+
+	/**
+	 * Constructor that takes a reference to a map as a base for the registry
+	 * entries
+	 */
+	public MapRegistryHandler(Map<String, AASDescriptor> rootMap) {
+		descriptorMap = rootMap;
+	}
+
+	@Override
+	public boolean contains(IIdentifier id) {
+		return descriptorMap.containsKey(id.getId());
+	}
+
+	@Override
+	public void remove(IIdentifier id) {
+		AASDescriptor removed = descriptorMap.remove(id.getId());
+
+		IIdentifier aasId = removed.getIdentifier();
+		if (!aasId.getId().equals(id.getId())) {
+			// id is an assetId => also remove the aasId-mapping
+			descriptorMap.remove(aasId.getId());
+		} else {
+			IAsset asset = removed.getAsset();
+			if (asset != null) {
+				IIdentifier assetId = asset.getIdentification();
+				descriptorMap.remove(assetId.getId());
+			}
+		}
+	}
+
+	@Override
+	public void insert(AASDescriptor descriptor) {
+		// insert with descriptor id
+		String id = descriptor.getIdentifier().getId();
+		descriptorMap.put(id, descriptor);
+
+		// insert with asset id if present
+		IAsset asset = descriptor.getAsset();
+		if (asset != null) {
+			String assetId = asset.getIdentification().getId();
+			descriptorMap.put(assetId, descriptor);
+		}
+	}
+
+	@Override
+	public void update(AASDescriptor descriptor) {
+		insert(descriptor); // has no semantic difference for hashmaps
+	}
+
+	@Override
+	public AASDescriptor get(IIdentifier id) {
+		return descriptorMap.get(id.getId());
+	}
+
+	@Override
+	public List<AASDescriptor> getAll() {
+		return new ArrayList<>(new HashSet<>(descriptorMap.values()));
+	}
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/proxy/AASRegistryProxy.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/proxy/AASRegistryProxy.java
index a84b403..c5c5380 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/proxy/AASRegistryProxy.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/proxy/AASRegistryProxy.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.aas.registration.proxy;
 
 import java.io.UnsupportedEncodingException;
@@ -9,16 +18,16 @@
 
 import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
 import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
-import org.eclipse.basyx.aas.registration.api.IAASRegistryService;
-import org.eclipse.basyx.aas.registration.restapi.DirectoryModelProvider;
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
+import org.eclipse.basyx.aas.registration.restapi.AASRegistryModelProvider;
 import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
 import org.eclipse.basyx.vab.coder.json.connector.JSONConnector;
-import org.eclipse.basyx.vab.directory.proxy.VABDirectoryProxy;
 import org.eclipse.basyx.vab.exception.provider.ProviderException;
 import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
 import org.eclipse.basyx.vab.modelprovider.VABPathTools;
 import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
 import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnector;
+import org.eclipse.basyx.vab.registry.proxy.VABRegistryProxy;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -27,10 +36,10 @@
 /**
  * Local proxy class that hides HTTP calls to BaSys registry
  * 
- * @author kuhn
+ * @author kuhn, schnicke
  *
  */
-public class AASRegistryProxy extends VABDirectoryProxy implements IAASRegistryService {
+public class AASRegistryProxy extends VABRegistryProxy implements IAASRegistry {
 	
 	private static Logger logger = LoggerFactory.getLogger(AASRegistryProxy.class);
 
@@ -41,7 +50,20 @@
 	 *            The endpoint of the registry with a HTTP-REST interface
 	 */
 	public AASRegistryProxy(String registryUrl) {
-		this(new JSONConnector(new HTTPConnector(registryUrl)));
+		this(new JSONConnector(new HTTPConnector(harmonizeURL(registryUrl))));
+	}
+
+	/**
+	 * Removes prefix if it exists since it will be readded at a later stage
+	 * 
+	 * @param url
+	 * @return
+	 */
+	private static String harmonizeURL(String url) {
+		if (url.endsWith(AASRegistryModelProvider.PREFIX)) {
+			url = url.substring(0, url.length() - AASRegistryModelProvider.PREFIX.length());
+		}
+		return url;
 	}
 
 	/**
@@ -55,7 +77,7 @@
 	}
 
 	private static VABElementProxy createProxy(IModelProvider provider) {
-		return new VABElementProxy(DirectoryModelProvider.PREFIX, provider);
+		return new VABElementProxy(AASRegistryModelProvider.PREFIX, provider);
 	}
 
 	/**
@@ -69,7 +91,7 @@
 
 			// Typically, VAB SET should not create new entries. Nevertheless, the registry
 			// API is defined to do it.
-			provider.setModelPropertyValue(encodedId, deviceAASDescriptor);
+			provider.setValue(encodedId, deviceAASDescriptor);
 		} catch (Exception e) {
 			if (e instanceof ProviderException) {
 				throw (ProviderException) e;
@@ -98,7 +120,7 @@
 	@Override @SuppressWarnings("unchecked")
 	public AASDescriptor lookupAAS(IIdentifier aasIdentifier) throws ProviderException {
 		try {
-			Object result = provider.getModelPropertyValue(URLEncoder.encode(aasIdentifier.getId(), "UTF-8"));
+			Object result = provider.getValue(URLEncoder.encode(aasIdentifier.getId(), "UTF-8"));
 			return new AASDescriptor((Map<String, Object>) result);
 		} catch (Exception e) {
 			if (e instanceof ProviderException) {
@@ -113,7 +135,7 @@
 	@Override
 	public List<AASDescriptor> lookupAll() throws ProviderException {
 		try {
-			Object result = provider.getModelPropertyValue("");
+			Object result = provider.getValue("");
 			Collection<?> descriptors = (Collection<?>) result;
 			return descriptors.stream().map(x -> new AASDescriptor((Map<String, Object>) x)).collect(Collectors.toList());
 		} catch (Exception e) {
@@ -130,7 +152,7 @@
 		try {
 			// Typically, VAB SET should not create new entries. Nevertheless, the registry
 			// API is defined to do it.
-			provider.setModelPropertyValue(VABPathTools.concatenatePaths(buildSubmodelPath(aas), smDescriptor.getIdShort()), smDescriptor);
+			provider.setValue(VABPathTools.concatenatePaths(buildSubmodelPath(aas), URLEncoder.encode(smDescriptor.getIdentifier().getId(), "UTF-8")), smDescriptor);
 		} catch (Exception e) {
 			if (e instanceof ProviderException) {
 				throw (ProviderException) e;
@@ -141,9 +163,9 @@
 	}
 
 	@Override
-	public void delete(IIdentifier aasId, String smIdShort) throws ProviderException {
+	public void delete(IIdentifier aasId, IIdentifier smId) throws ProviderException {
 		try {
-			provider.deleteValue(VABPathTools.concatenatePaths(buildSubmodelPath(aasId), URLEncoder.encode(smIdShort, "UTF-8")));
+			provider.deleteValue(VABPathTools.concatenatePaths(buildSubmodelPath(aasId), URLEncoder.encode(smId.getId(), "UTF-8")));
 		} catch (Exception e) {
 			if (e instanceof ProviderException) {
 				throw (ProviderException) e;
@@ -156,7 +178,38 @@
 	private String buildSubmodelPath(IIdentifier aas) throws ProviderException {
 		// Encode id to handle usage of reserved symbols, e.g. /
 		String encodedAASId = VABPathTools.encodePathElement(aas.getId());
-		return VABPathTools.concatenatePaths(encodedAASId, DirectoryModelProvider.SUBMODELS);
+		return VABPathTools.concatenatePaths(encodedAASId, AASRegistryModelProvider.SUBMODELS);
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public List<SubmodelDescriptor> lookupSubmodels(IIdentifier aasId) throws ProviderException {
+		try {
+			Object result = provider.getValue(VABPathTools.concatenatePaths(buildSubmodelPath(aasId)));
+			Collection<?> descriptors = (Collection<?>) result;
+			return descriptors.stream().map(x -> new SubmodelDescriptor((Map<String, Object>) x)).collect(Collectors.toList());
+		} catch (Exception e) {
+			if (e instanceof ProviderException) {
+				throw (ProviderException) e;
+			} else {
+				throw new ProviderException(e);
+			}
+		}
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public SubmodelDescriptor lookupSubmodel(IIdentifier aasId, IIdentifier smId) throws ProviderException {
+		try {
+			Object result = provider.getValue(VABPathTools.concatenatePaths(buildSubmodelPath(aasId), URLEncoder.encode(smId.getId(), "UTF-8")));
+			return new SubmodelDescriptor((Map<String, Object>) result);
+		} catch (Exception e) {
+			if (e instanceof ProviderException) {
+				throw (ProviderException) e;
+			} else {
+				throw new ProviderException(e);
+			}
+		}
 	}
 }
 
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/restapi/AASRegistryModelProvider.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/restapi/AASRegistryModelProvider.java
new file mode 100644
index 0000000..be780dc
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/restapi/AASRegistryModelProvider.java
@@ -0,0 +1,328 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.aas.registration.restapi;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.util.Collection;
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
+import org.eclipse.basyx.aas.registration.memory.InMemoryRegistry;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.submodel.metamodel.map.modeltype.ModelType;
+import org.eclipse.basyx.vab.exception.provider.MalformedRequestException;
+import org.eclipse.basyx.vab.exception.provider.ProviderException;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.eclipse.basyx.vab.modelprovider.VABPathTools;
+import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
+
+/**
+ * Connects an arbitrary IRegistryService implementation to the VAB
+ * 
+ * @author schnicke, conradi
+ *
+ */
+public class AASRegistryModelProvider implements IModelProvider {
+
+	IAASRegistry registry;
+
+	public static final String PREFIX = "api/v1/registry";
+	public static final String SUBMODELS = "submodels";
+
+	public AASRegistryModelProvider(IAASRegistry registry) {
+		this.registry = registry;
+	}
+
+	public AASRegistryModelProvider() {
+		this(new InMemoryRegistry());
+	}
+
+	/**
+	 * Check for correctness of path and returns a stripped path (i.e. no leading
+	 * prefix)
+	 * 
+	 * @param path
+	 * @return
+	 * @throws MalformedRequestException if path does not start with PERFIX "api/v1/registry"
+	 */
+	private String stripPrefix(String path) throws MalformedRequestException {
+		path = VABPathTools.stripSlashes(path);
+		if (!path.startsWith(PREFIX)) {
+			throw new MalformedRequestException("Path " + path + " not recognized as registry path. Has to start with " + PREFIX);
+		}
+		path = path.replaceFirst(PREFIX, "");
+		path = VABPathTools.stripSlashes(path);
+		return path;
+	}
+	
+	/**
+	 * Splits a path and checks, that first element is not "submodels" and that the second one, if exists, is "submodels"
+	 * 
+	 * @param path the path to be splitted
+	 * @return Array of path elements
+	 * @throws MalformedRequestException if path is not valid
+	 */
+	private String[] splitPath(String path) throws MalformedRequestException {
+		
+		if(path.isEmpty()) {
+			return new String[0];
+		}
+		
+		String[] splitted = path.split("/");
+		
+		//Assumes "submodels" is not a valid AASId
+		if(splitted[0].equals(SUBMODELS)) {
+			throw new MalformedRequestException("Path must not start with " + SUBMODELS);
+		}
+		
+		//If path contains more than one element, the second one has to be "submodels"
+		if(splitted.length > 1 && !splitted[1].equals(SUBMODELS)) {
+			throw new MalformedRequestException("Second path element must be (if present): " + SUBMODELS);
+		}
+		
+		return splitted;
+	}
+	
+	private String[] preparePath(String path) throws MalformedRequestException {
+		path = stripPrefix(path);
+
+		String[] splitted = splitPath(path);
+
+		try {
+			for (int i = 0; i < splitted.length; i++) {
+				splitted[i] = URLDecoder.decode(splitted[i], "UTF-8");
+			}
+			return splitted;
+		} catch (UnsupportedEncodingException e) {
+			//Malformed request because of unsupported encoding
+			throw new MalformedRequestException("Path has to be encoded as UTF-8 string.");
+		}
+	}
+	
+	/**
+	 * Checks if a given Object is a Map and checks if it has the correct modelType
+	 * 
+	 * @param expectedModelType the modelType the Object is expected to have
+	 * @param value the Object to be checked and casted
+	 * @return the object casted to a Map
+	 * @throws MalformedRequestException 
+	 */
+	@SuppressWarnings("unchecked")
+	private Map<String, Object> checkModelType(String expectedModelType, Object value) throws MalformedRequestException {
+		//check if the given value is a Map
+		if(!(value instanceof Map)) {
+			throw new MalformedRequestException("Given newValue is not a Map");
+		}
+
+		Map<String, Object> map = (Map<String, Object>) value;
+		
+		//check if the given Map contains an AAS
+		String type = ModelType.createAsFacade(map).getName();
+		
+		//have to accept Objects without modeltype information,
+		//as modeltype is not part of the public metamodel
+		if(!expectedModelType.equals(type) && type != null) {
+			throw new MalformedRequestException("Given newValue map has not the correct ModelType");
+		}
+		
+		return map;
+	}
+	
+	/**
+	 * Makes sure, that given Object is an AASDescriptor by checking its ModelType<br />
+	 * Creates a new AASDescriptor with the content of the given Map
+	 * 
+	 * @param value the AAS Map object
+	 * @return an AAS
+	 * @throws MalformedRequestException 
+	 */
+	private AASDescriptor createAASDescriptorFromMap(Object value) throws MalformedRequestException {
+		Map<String, Object> map = checkModelType(AASDescriptor.MODELTYPE, value);
+		AASDescriptor aasDescriptor = new AASDescriptor(map);
+		return aasDescriptor;
+	}
+	
+	/**
+	 * Makes sure, that given Object is an SubmodelDescriptor by checking its ModelType<br />
+	 * Creates a new SubmodelDescriptor with the content of the given Map
+	 * 
+	 * @param value the AAS Map object
+	 * @return an AAS
+	 * @throws MalformedRequestException 
+	 */
+	private SubmodelDescriptor createSMDescriptorFromMap(Object value) throws MalformedRequestException {
+		Map<String, Object> map = checkModelType(SubmodelDescriptor.MODELTYPE, value);
+		SubmodelDescriptor smDescriptor = new SubmodelDescriptor(map);
+		return smDescriptor;
+	}
+
+	@Override
+	public Object getValue(String path) throws ProviderException {
+		String[] splitted = preparePath(path);
+
+		//Path is empty, request for all AASDescriptors
+		if (splitted.length == 0) {
+			return registry.lookupAll();
+		} else {
+			
+			//Given path consists only of an AAS Id
+			if(splitted.length == 1) {
+				AASDescriptor descriptor = registry.lookupAAS(new ModelUrn(splitted[0]));
+				
+				//Throw an Exception if the requested AAS does not exist 
+				if(descriptor == null) {
+					throw new ResourceNotFoundException("Specified AASid '" + splitted[0] + "' does not exist.");
+				}
+				return descriptor;
+			
+			//Given path consists of an AAS Id and "/submodels"
+			//Request for all SubmodelDescriptors of given AAS
+			} else if(splitted.length == 2) {
+				return getSmDescriptorsFromAAS(new ModelUrn(splitted[0]));
+			
+			//Given path consists of an AAS Id and "/submodels/" and a SubmodelId
+			//Request for the SubmodelDescriptor of given AAS with given id
+			} else if(splitted.length == 3) {
+				SubmodelDescriptor smDescriptor = getSmDescriptorFromAAS(new ModelUrn(splitted[0]), splitted[2]);
+				if(smDescriptor == null) {
+					throw new ResourceNotFoundException("Specified SubmodelId '" + splitted[2] + "' does not exist in AAS '" + splitted[0] + "'.");
+				}
+				return smDescriptor;
+			}
+			
+			//path has more than three elements and is therefore invalid
+			throw new MalformedRequestException("Given path '" + path + "' contains more than three path elements and is therefore invalid.");
+		}
+	}
+
+	@Override
+	public void setValue(String path, Object newValue) throws ProviderException {
+		String[] splitted = preparePath(path);
+
+		if (splitted.length > 0) { // Overwriting existing entry
+			//if path contains more or less than an aasID after the prefix
+
+			// Decode encoded path
+			ModelUrn identifier = new ModelUrn(splitted[0]);
+			
+			if (splitted.length == 1) {
+				// Typically, VAB SET should not create new entries. Nevertheless, the registry
+				// API is defined to do it.
+				AASDescriptor desc = createAASDescriptorFromMap(newValue);
+
+				// Ensure the passed identifier is equals the
+				String descId = desc.getIdentifier().getId();
+				String urlId = splitted[0];
+				if (descId.equals(urlId)) {
+					registry.register(desc);
+				} else {
+					throw new MalformedRequestException("The Identifier " + descId + " in the descriptor does not match the URL with id " + urlId);
+				}
+			} else if (splitted.length == 3) {
+				SubmodelDescriptor smDesc = createSMDescriptorFromMap(newValue);
+				registry.register(identifier, smDesc);
+			} else {
+				throw new MalformedRequestException("Unknown path " + path);
+			}
+		} else {
+			throw new MalformedRequestException("Set with empty path is not supported by registry");
+		}
+	}
+
+	@Override
+	public void createValue(String path, Object newEntity) throws ProviderException {
+		throw new MalformedRequestException("Create (POST) on a registry is not supported. Please, use put");
+	}
+
+	@Override
+	public void deleteValue(String path) throws ProviderException {
+		String[] splitted = preparePath(path);
+			
+		if (splitted.length == 1) { //delete an aas
+			
+			ModelUrn aasId = new ModelUrn(splitted[0]);
+			
+			//aas to be deleted does not exist
+			if(registry.lookupAAS(aasId) == null) {
+				throw new ResourceNotFoundException("AAS '" + splitted[0] + "' to be deleted does not exist.");
+			}
+			
+			registry.delete(aasId);
+			
+		} else if(splitted.length == 3) { //delete a submodel
+			ModelUrn aasId = new ModelUrn(splitted[0]);
+			String smId = splitted[2];
+			// a submodel with this Id does not exist in given aas
+			// getSmDescriptorFromAAS also checks if aas exists
+			SubmodelDescriptor smDesc = getSmDescriptorFromAAS(aasId, smId);
+			if (smDesc == null) {
+				throw new ResourceNotFoundException("A Submodel with id '" + smId + "' does not exist in aas '" + splitted[0] + "'.");
+			}
+
+			registry.delete(aasId, smDesc.getIdentifier());
+		} else {
+			throw new MalformedRequestException("Delete with empty path is not supported by registry");
+		}
+	}
+
+	@Override
+	public void deleteValue(String path, Object obj) throws ProviderException {
+		throw new MalformedRequestException("DeleteValue with parameter not supported by registry");
+	}
+
+	@Override
+	public Object invokeOperation(String path, Object... parameter) throws ProviderException {
+		throw new MalformedRequestException("Invoke not supported by registry");
+	}
+	
+	/**
+	 * Gets all SubmodelDescriptor objects form an aas.
+	 * Throws RuntimeException if aas does not exist.
+	 * 
+	 * @param id id of the aas
+	 * @return Set of contained SubmodelDescriptor objects
+	 * @throws ResourceNotFoundException if the AAS does not exist
+	 */
+	private Collection<SubmodelDescriptor> getSmDescriptorsFromAAS(IIdentifier id) throws ResourceNotFoundException {
+		AASDescriptor aasDescriptor = registry.lookupAAS(id);
+		if(aasDescriptor == null) {
+			throw new ResourceNotFoundException("Specified AASid '" + id.getId() + "' does not exist.");
+		}
+		return aasDescriptor.getSubmodelDescriptors();
+	}
+	
+	/**
+	 * Gets a specific SubmodelDescriptor form an aas.
+	 * Throws RuntimeException if aas does not exist.
+	 * 
+	 * @param aasId id of the aas
+	 * @param smId id of the submodel
+	 * @return the SubmodelDescriptor with the given id
+	 * @throws ResourceNotFoundException if aasId does not exist
+	 */
+	private SubmodelDescriptor getSmDescriptorFromAAS(IIdentifier aasId, String smId)
+			throws ResourceNotFoundException {
+		AASDescriptor aasDescriptor = registry.lookupAAS(aasId);
+		if(aasDescriptor == null) {
+			throw new ResourceNotFoundException("Specified AASId '" + aasId.getId() + "' does not exist.");
+		}
+		
+		SubmodelDescriptor smDescriptor = aasDescriptor.getSubmodelDescriptorFromIdentifierId(smId);
+		if (smDescriptor == null) {
+			throw new ResourceNotFoundException("Specified SMId '" + smId + "' for AAS " + aasId.getId() + " does not exist.");
+		}
+		return smDescriptor;
+	}
+
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/restapi/DirectoryModelProvider.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/restapi/DirectoryModelProvider.java
deleted file mode 100644
index f2072d0..0000000
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/restapi/DirectoryModelProvider.java
+++ /dev/null
@@ -1,347 +0,0 @@
-package org.eclipse.basyx.aas.registration.restapi;
-
-import java.io.UnsupportedEncodingException;
-import java.net.URLDecoder;
-import java.util.Collection;
-import java.util.Map;
-
-import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
-import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
-import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
-import org.eclipse.basyx.aas.registration.api.IAASRegistryService;
-import org.eclipse.basyx.aas.registration.memory.InMemoryRegistry;
-import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
-import org.eclipse.basyx.submodel.metamodel.map.modeltype.ModelType;
-import org.eclipse.basyx.vab.exception.provider.MalformedRequestException;
-import org.eclipse.basyx.vab.exception.provider.ProviderException;
-import org.eclipse.basyx.vab.exception.provider.ResourceAlreadyExistsException;
-import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
-import org.eclipse.basyx.vab.modelprovider.VABPathTools;
-import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
-
-/**
- * Connects an arbitrary IRegistryService implementation to the VAB
- * 
- * @author schnicke, conradi
- *
- */
-public class DirectoryModelProvider implements IModelProvider {
-
-	IAASRegistryService registry;
-
-	public static final String PREFIX = "api/v1/registry";
-	public static final String SUBMODELS = "submodels";
-
-	public DirectoryModelProvider(IAASRegistryService registry) {
-		this.registry = registry;
-	}
-
-	public DirectoryModelProvider() {
-		this(new InMemoryRegistry());
-	}
-
-	/**
-	 * Check for correctness of path and returns a stripped path (i.e. no leading
-	 * prefix)
-	 * 
-	 * @param path
-	 * @return
-	 * @throws MalformedRequestException if path does not start with PERFIX "api/v1/registry"
-	 */
-	private String stripPrefix(String path) throws MalformedRequestException {
-		path = VABPathTools.stripSlashes(path);
-		if (!path.startsWith(PREFIX)) {
-			throw new MalformedRequestException("Path " + path + " not recognized as registry path. Has to start with " + PREFIX);
-		}
-		path = path.replaceFirst(PREFIX, "");
-		path = VABPathTools.stripSlashes(path);
-		return path;
-	}
-	
-	/**
-	 * Splits a path and checks, that first element is not "submodels" and that the second one, if exists, is "submodels"
-	 * 
-	 * @param path the path to be splitted
-	 * @return Array of path elements
-	 * @throws MalformedRequestException if path is not valid
-	 */
-	private String[] splitPath(String path) throws MalformedRequestException {
-		
-		if(path.isEmpty()) {
-			return new String[0];
-		}
-		
-		String[] splitted = path.split("/");
-		
-		//Assumes "submodels" is not a valid AASId
-		if(splitted[0].equals(SUBMODELS)) {
-			throw new MalformedRequestException("Path must not start with " + SUBMODELS);
-		}
-		
-		//If path contains more than one element, the second one has to be "submodels"
-		if(splitted.length > 1 && !splitted[1].equals(SUBMODELS)) {
-			throw new MalformedRequestException("Second path element must be (if present): " + SUBMODELS);
-		}
-		
-		return splitted;
-	}
-	
-	private String[] preparePath(String path) throws MalformedRequestException {
-		path = stripPrefix(path);
-
-		String[] splitted = splitPath(path);
-
-		try {
-			for (int i = 0; i < splitted.length; i++) {
-				splitted[i] = URLDecoder.decode(splitted[i], "UTF-8");
-			}
-			return splitted;
-		} catch (UnsupportedEncodingException e) {
-			//Malformed request because of unsupported encoding
-			throw new MalformedRequestException("Path has to be encoded as UTF-8 string.");
-		}
-	}
-	
-	/**
-	 * Checks if a given Object is a Map and checks if it has the correct modelType
-	 * 
-	 * @param expectedModelType the modelType the Object is expected to have
-	 * @param value the Object to be checked and casted
-	 * @return the object casted to a Map
-	 * @throws MalformedRequestException 
-	 */
-	@SuppressWarnings("unchecked")
-	private Map<String, Object> checkModelType(String expectedModelType, Object value) throws MalformedRequestException {
-		//check if the given value is a Map
-		if(!(value instanceof Map)) {
-			throw new MalformedRequestException("Given newValue is not a Map");
-		}
-
-		Map<String, Object> map = (Map<String, Object>) value;
-		
-		//check if the given Map contains an AAS
-		String type = ModelType.createAsFacade(map).getName();
-		
-		//have to accept Objects without modeltype information,
-		//as modeltype is not part of the public metamodel
-		if(!expectedModelType.equals(type) && type != null) {
-			throw new MalformedRequestException("Given newValue map has not the correct ModelType");
-		}
-		
-		return map;
-	}
-	
-	/**
-	 * Makes sure, that given Object is an AASDescriptor by checking its ModelType<br />
-	 * Creates a new AASDescriptor with the content of the given Map
-	 * 
-	 * @param value the AAS Map object
-	 * @return an AAS
-	 * @throws MalformedRequestException 
-	 */
-	private AASDescriptor createAASDescriptorFromMap(Object value) throws MalformedRequestException {
-		Map<String, Object> map = checkModelType(AASDescriptor.MODELTYPE, value);
-		AASDescriptor aasDescriptor = new AASDescriptor(map);
-		return aasDescriptor;
-	}
-	
-	/**
-	 * Makes sure, that given Object is an SubmodelDescriptor by checking its ModelType<br />
-	 * Creates a new SubmodelDescriptor with the content of the given Map
-	 * 
-	 * @param value the AAS Map object
-	 * @return an AAS
-	 * @throws MalformedRequestException 
-	 */
-	private SubmodelDescriptor createSMDescriptorFromMap(Object value) throws MalformedRequestException {
-		Map<String, Object> map = checkModelType(SubmodelDescriptor.MODELTYPE, value);
-		SubmodelDescriptor smDescriptor = new SubmodelDescriptor(map);
-		return smDescriptor;
-	}
-
-	@Override
-	public Object getModelPropertyValue(String path) throws ProviderException {
-		String[] splitted = preparePath(path);
-
-		//Path is empty, request for all AASDescriptors
-		if (splitted.length == 0) {
-			return registry.lookupAll();
-		} else {
-			
-			//Given path consists only of an AAS Id
-			if(splitted.length == 1) {
-				AASDescriptor descriptor = registry.lookupAAS(new ModelUrn(splitted[0]));
-				
-				//Throw an Exception if the requested AAS does not exist 
-				if(descriptor == null) {
-					throw new ResourceNotFoundException("Specified AASid '" + splitted[0] + "' does not exist.");
-				}
-				return descriptor;
-			
-			//Given path consists of an AAS Id and "/submodels"
-			//Request for all SubmodelDescriptors of given AAS
-			} else if(splitted.length == 2) {
-				return getSmDescriptorsFromAAS(new ModelUrn(splitted[0]));
-			
-			//Given path consists of an AAS Id and "/submodels/" and a SubmodelId
-			//Request for the SubmodelDescriptor of given AAS with given id
-			} else if(splitted.length == 3) {
-				SubmodelDescriptor smDescriptor = getSmDescriptorFromAAS(new ModelUrn(splitted[0]), splitted[2]);
-				if(smDescriptor == null) {
-					throw new ResourceNotFoundException("Specified SubmodelId '" + splitted[2] + "' does not exist in AAS '" + splitted[0] + "'.");
-				}
-				return smDescriptor;
-			}
-			
-			//path has more than three elements and is therefore invalid
-			throw new MalformedRequestException("Given path '" + path + "' contains more than three path elements and is therefore invalid.");
-		}
-	}
-
-	@Override
-	public void setModelPropertyValue(String path, Object newValue) throws ProviderException {
-		String[] splitted = preparePath(path);
-
-		if (splitted.length > 0) { // Overwriting existing entry
-			//if path contains more or less than an aasID after the prefix
-
-			// Decode encoded path
-			ModelUrn identifier = new ModelUrn(splitted[0]);
-			
-			if (splitted.length == 1) {
-				// Typically, VAB SET should not create new entries. Nevertheless, the registry
-				// API is defined to do it.
-				registry.register(createAASDescriptorFromMap(newValue));
-			} else if (splitted.length == 3) {
-				SubmodelDescriptor smDesc = createSMDescriptorFromMap(newValue);
-				registry.register(identifier, smDesc);
-			} else {
-				throw new MalformedRequestException("Unknown path " + path);
-			}
-		} else {
-			throw new MalformedRequestException("Set with empty path is not supported by registry");
-		}
-	}
-
-	@Override
-	public void createValue(String path, Object newEntity) throws ProviderException {
-		String[] splitted = preparePath(path);
-
-		// Creating new entry
-		if (splitted.length == 0) {
-			
-			AASDescriptor aas = createAASDescriptorFromMap(newEntity);
-			
-			// Check if resource does already exist
-			try {
-				registry.lookupAAS(aas.getIdentifier());
-				throw new ResourceAlreadyExistsException("AAS with Id '" +
-						aas.getIdentifier().getId() + "' already exists. Try update instead.");
-			} catch (ResourceNotFoundException e) {
-				registry.register(aas);
-			}
-			
-		// Creating new submodel entry for existing aas
-		} else if (splitted.length == 2) { 
-			ModelUrn aasId = retrieveModelURN(splitted[0]);
-			
-			SubmodelDescriptor smDescriptor = createSMDescriptorFromMap(newEntity);
-			
-			//a submodel with this Id already exists in given aas
-			//getSmDescriptorFromAAS also checks if aas exists
-			try {
-				getSmDescriptorFromAAS(aasId, smDescriptor.getIdShort());
-				throw new ResourceAlreadyExistsException("A Submodel with id '" + smDescriptor.getIdShort() +
-						"' already exists in aas '" + splitted[0] + "'. Try update instead.");
-			} catch (ResourceNotFoundException e) {
-				registry.register(aasId, smDescriptor);
-			}
-		} else {
-			throw new MalformedRequestException("Create was called with an unsupported path: " + path);
-		}
-	}
-
-	private ModelUrn retrieveModelURN(String str) {
-		return new ModelUrn(str);
-	}
-
-	@Override
-	public void deleteValue(String path) throws ProviderException {
-		String[] splitted = preparePath(path);
-			
-		if (splitted.length == 1) { //delete an aas
-			
-			ModelUrn aasId = new ModelUrn(splitted[0]);
-			
-			//aas to be deleted does not exist
-			if(registry.lookupAAS(aasId) == null) {
-				throw new ResourceNotFoundException("AAS '" + splitted[0] + "' to be deleted does not exist.");
-			}
-			
-			registry.delete(aasId);
-			
-		} else if(splitted.length == 3) { //delete a submodel
-			ModelUrn aasId = new ModelUrn(splitted[0]);
-			String smId = splitted[2];
-			// a submodel with this Id does not exist in given aas
-			// getSmDescriptorFromAAS also checks if aas exists
-			if (getSmDescriptorFromAAS(aasId, smId) == null) {
-				throw new ResourceNotFoundException("A Submodel with id '" + smId + "' does not exist in aas '" + splitted[0] + "'.");
-			}
-
-			registry.delete(aasId, smId);
-		} else {
-			throw new MalformedRequestException("Delete with empty path is not supported by registry");
-		}
-	}
-
-	@Override
-	public void deleteValue(String path, Object obj) throws ProviderException {
-		throw new MalformedRequestException("DeleteValue with parameter not supported by registry");
-	}
-
-	@Override
-	public Object invokeOperation(String path, Object... parameter) throws ProviderException {
-		throw new MalformedRequestException("Invoke not supported by registry");
-	}
-	
-	/**
-	 * Gets all SubmodelDescriptor objects form an aas.
-	 * Throws RuntimeException if aas does not exist.
-	 * 
-	 * @param id id of the aas
-	 * @return Set of contained SubmodelDescriptor objects
-	 * @throws ResourceNotFoundException if the AAS does not exist
-	 */
-	private Collection<SubmodelDescriptor> getSmDescriptorsFromAAS(IIdentifier id) throws ResourceNotFoundException {
-		AASDescriptor aasDescriptor = registry.lookupAAS(id);
-		if(aasDescriptor == null) {
-			throw new ResourceNotFoundException("Specified AASid '" + id.getId() + "' does not exist.");
-		}
-		return aasDescriptor.getSubModelDescriptors();
-	}
-	
-	/**
-	 * Gets a specific SubmodelDescriptor form an aas.
-	 * Throws RuntimeException if aas does not exist.
-	 * 
-	 * @param aasId id of the aas
-	 * @param smId id of the submodel
-	 * @return the SubmodelDescriptor with the given id
-	 * @throws ResourceNotFoundException if aasId does not exist
-	 */
-	private SubmodelDescriptor getSmDescriptorFromAAS(IIdentifier aasId, String smId)
-			throws ResourceNotFoundException {
-		AASDescriptor aasDescriptor = registry.lookupAAS(aasId);
-		if(aasDescriptor == null) {
-			throw new ResourceNotFoundException("Specified AASId '" + aasId.getId() + "' does not exist.");
-		}
-		
-		SubmodelDescriptor smDescriptor = aasDescriptor.getSubmodelDescriptorFromIdShort(smId);
-		if (smDescriptor == null) {
-			throw new ResourceNotFoundException("Specified SMId '" + smId + "' for AAS " + aasId.getId() + " does not exist.");
-		}
-		return smDescriptor;
-	}
-
-}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/restapi/AASModelProvider.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/restapi/AASModelProvider.java
index d4ea4f8..47b07bc 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/restapi/AASModelProvider.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/restapi/AASModelProvider.java
@@ -1,10 +1,20 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.aas.restapi;
 
 import java.util.Map;
 
 import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
 import org.eclipse.basyx.aas.restapi.api.IAASAPI;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.aas.restapi.vab.VABAASAPI;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
 import org.eclipse.basyx.vab.exception.provider.MalformedRequestException;
 import org.eclipse.basyx.vab.exception.provider.NotAnInvokableException;
 import org.eclipse.basyx.vab.exception.provider.ProviderException;
@@ -13,8 +23,8 @@
 import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaProvider;
 
 /**
- * Model provider explicitely meant to implement the access to the AAS object. This excludes access to the submodels,
- * that are wrapped into their own provider.
+ * Model provider explicitely meant to implement the access to the AAS object.
+ * This excludes access to the submodels, that are wrapped into their own provider.
  * 
  * @author espen
  *
@@ -24,7 +34,8 @@
 	private IAASAPI aasApi;
 
 	/**
-	 * Constructor based on the model provider containing the AAS model
+	 * Constructor based on the model provider containing the AAS model. This is based
+	 * on the default AAS API
 	 */
 	public AASModelProvider(IModelProvider modelProvider) {
 		aasApi = new VABAASAPI(modelProvider);
@@ -47,7 +58,7 @@
 	}
 
 	@Override
-	public Object getModelPropertyValue(String path) throws ProviderException {
+	public Object getValue(String path) throws ProviderException {
 		path = preparePath(path);
 		if (path.isEmpty()) {
 			return aasApi.getAAS();
@@ -57,7 +68,7 @@
 	}
 
 	@Override
-	public void setModelPropertyValue(String path, Object newValue) throws ProviderException {
+	public void setValue(String path, Object newValue) throws ProviderException {
 		throw new MalformedRequestException("For an AAS, Set is not supported");
 	}
 
@@ -67,7 +78,9 @@
 		path = preparePath(path);
 		if (path.equals("submodels")) {
 			Map<String, Object> smMap = (Map<String, Object>) newEntity;
-			SubModel sm = SubModel.createAsFacade(smMap);
+			Submodel sm = Submodel.createAsFacade(smMap);
+			// It is allowed to overwrite existing submodels
+			aasApi.removeSubmodel(sm.getIdentification().getId());
 			aasApi.addSubmodel(sm.getReference());
 		} else {
 			throw new MalformedRequestException("Path " + path + " is not supported");
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/restapi/MultiAASProvider.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/restapi/MultiAASProvider.java
deleted file mode 100644
index 2ae86be..0000000
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/restapi/MultiAASProvider.java
+++ /dev/null
@@ -1,159 +0,0 @@
-package org.eclipse.basyx.aas.restapi;
-
-import java.util.HashMap;
-
-import org.eclipse.basyx.vab.exception.provider.ProviderException;
-import org.eclipse.basyx.vab.modelprovider.VABPathTools;
-import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
-
-/**
- * Provider, that redirects requests for different Asset Administration Shells.
- * e.g. aas1 refers to the AAS with id "aas1".
- * 
- * @author espen
- *
- */
-public class MultiAASProvider implements IModelProvider {
-	protected HashMap<String, VABMultiSubmodelProvider> aas_providers;
-
-	public MultiAASProvider() {
-		aas_providers = new HashMap<>();
-	}
-
-	/**
-	 * Adds an Asset Administration Shell to this provider. The AAS will be
-	 * accessible via *id
-	 * 
-	 * @param aasIdShort
-	 *            The id of the added Asset Administration Shell.
-	 * @param modelProvider
-	 *            The provider that contains the Asset Administration Shell.
-	 */
-	public void addMultiSubmodelProvider(String aasIdShort, VABMultiSubmodelProvider modelProvider) {
-		aas_providers.put(aasIdShort, modelProvider);
-	}
-
-	/**
-	 * Removes all connected Asset Administration Shells from this provider
-	 */
-	public void clear() {
-		aas_providers.clear();
-	}
-
-	@Override
-	public Object getModelPropertyValue(String path) throws ProviderException {
-		String aasId = getId(path);
-		if (aasId != null) {
-			VABMultiSubmodelProvider provider = aas_providers.get(aasId);
-			if (provider == null) {
-				return null;
-			}
-			String subPath = getSubPath(path, aasId);
-			return provider.getModelPropertyValue(subPath);
-		}
-		return null;
-	}
-
-	@Override
-	public void setModelPropertyValue(String path, Object newValue) throws ProviderException {
-		String aasId = getId(path);
-		if (aasId != null) {
-			VABMultiSubmodelProvider provider = aas_providers.get(aasId);
-			if (provider == null) {
-				return;
-			}
-			String subPath = getSubPath(path, aasId);
-			provider.setModelPropertyValue(subPath, newValue);
-		}
-	}
-
-	@Override
-	public void createValue(String path, Object newEntity) throws ProviderException {
-		String aasId = getId(path);
-		if (aasId != null) {
-			VABMultiSubmodelProvider provider = aas_providers.get(aasId);
-			if (provider == null) {
-				return;
-			}
-			String subPath = getSubPath(path, aasId);
-			provider.createValue(subPath, newEntity);
-		}
-	}
-
-	@Override
-	public void deleteValue(String path) throws ProviderException {
-		String aasId = getId(path);
-		if (aasId != null) {
-			VABMultiSubmodelProvider provider = aas_providers.get(aasId);
-			if (provider == null) {
-				return;
-			}
-			String subPath = getSubPath(path, aasId);
-			provider.deleteValue(subPath);
-		}
-	}
-
-	@Override
-	public void deleteValue(String path, Object obj) throws ProviderException {
-		String aasId = getId(path);
-		if (aasId != null) {
-			VABMultiSubmodelProvider provider = aas_providers.get(aasId);
-			if (provider == null) {
-				return;
-			}
-			String subPath = getSubPath(path, aasId);
-			provider.deleteValue(subPath, obj);
-		}
-	}
-
-	@Override
-	public Object invokeOperation(String path, Object... parameter) throws ProviderException {
-		String aasId = getId(path);
-		if (aasId != null) {
-			VABMultiSubmodelProvider provider = aas_providers.get(aasId);
-			if (provider == null) {
-				return null;
-			}
-			String subPath = getSubPath(path, aasId);
-			return provider.invokeOperation(subPath, parameter);
-		}
-		return null;
-	}
-
-	/**
-	 * Returns the requested aas id from a given VAB path. E.g. returns "aas1", if
-	 * the path is aas1/aas/
-	 * 
-	 * @param path
-	 *            The requested VAB path
-	 * @return The id of the requested Asset Administration Shell. Returns null, if
-	 *         the path is invalid or does not contain an AAS id.
-	 */
-	private String getId(String path) {
-		if (path == null) {
-			return null;
-		}
-
-		String[] elements = VABPathTools.splitPath(path);
-		if (elements.length >= 1) {
-			String aasId = elements[0];
-			return aasId;
-		} else {
-			return null;
-		}
-	}
-
-	/**
-	 * Returns the sub path in the context of a given AAS id. E.g. returns
-	 * "/aas/submodels", if the path is aas1/aas/submodels/
-	 * 
-	 * @param path
-	 *            The requested VAB path
-	 * @param aasId
-	 *            The id of the requested Asset Administration Shell
-	 * @return The remaining sub-path, when removing the id from the VAB path
-	 */
-	private String getSubPath(String path, String aasId) {
-		return path.substring(aasId.length());
-	}
-}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/restapi/MultiSubmodelProvider.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/restapi/MultiSubmodelProvider.java
new file mode 100644
index 0000000..e2b4483
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/restapi/MultiSubmodelProvider.java
@@ -0,0 +1,527 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.aas.restapi;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
+import org.eclipse.basyx.aas.restapi.api.IAASAPI;
+import org.eclipse.basyx.aas.restapi.api.IAASAPIFactory;
+import org.eclipse.basyx.aas.restapi.vab.VABAASAPIFactory;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.restapi.SubmodelProvider;
+import org.eclipse.basyx.submodel.restapi.api.ISubmodelAPI;
+import org.eclipse.basyx.submodel.restapi.api.ISubmodelAPIFactory;
+import org.eclipse.basyx.submodel.restapi.vab.VABSubmodelAPIFactory;
+import org.eclipse.basyx.vab.exception.provider.MalformedRequestException;
+import org.eclipse.basyx.vab.exception.provider.ProviderException;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.eclipse.basyx.vab.modelprovider.VABPathTools;
+import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
+import org.eclipse.basyx.vab.protocol.api.IConnectorFactory;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorFactory;
+
+/**
+ * Provider class that implements the AssetAdministrationShellServices <br />
+ * This provider supports operations on multiple sub models that are selected by
+ * path<br />
+ * <br />
+ * Supported API:<br />
+ * - getModelPropertyValue<br />
+ * /aas Returns the Asset Administration Shell<br />
+ * /aas/submodels Retrieves all Submodels from the current Asset Administration
+ * Shell<br />
+ * /aas/submodels/{subModelId} Retrieves a specific Submodel from a specific
+ * Asset Administration Shell<br />
+ * /aas/submodels/{subModelId}/properties Retrieves all Properties from the
+ * current Submodel<br />
+ * /aas/submodels/{subModelId}/operations Retrieves all Operations from the
+ * current Submodel<br />
+ * /aas/submodels/{subModelId}/events Retrieves all Events from the current
+ * Submodel<br />
+ * /aas/submodels/{subModelId}/properties/{propertyId} Retrieves a specific
+ * property from the AAS's Submodel<br />
+ * /aas/submodels/{subModelId}/operations/{operationId} Retrieves a specific
+ * Operation from the AAS's Submodel<br />
+ * /aas/submodels/{subModelId}/events/{eventId} Retrieves a specific event from
+ * the AAS's submodel
+ * <br /><br />
+ * - createValue <br />
+ * /aas/submodels Adds a new Submodel to an existing Asset Administration Shell
+ * <br /><br />
+ * /aas/submodels/{subModelId}/properties Adds a new property to the AAS's
+ * submodel <br />
+ * /aas/submodels/{subModelId}/operations Adds a new operation to the AAS's
+ * submodel <br />
+ * /aas/submodels/{subModelId}/events Adds a new event to the AAS's submodel
+ * <br /><br />
+ * - invokeOperation<br />
+ * /aas/submodels/{subModelId}/operations/{operationId} Invokes a specific
+ * operation from the AAS' submodel with a list of input parameters
+ * <br /><br />
+ * - deleteValue<br />
+ * /aas/submodels/{subModelId} Deletes a specific Submodel from a specific Asset
+ * Administration Shell <br />
+ * /aas/submodels/{subModelId}/properties/{propertyId} Deletes a specific
+ * Property from the AAS's Submodel<br />
+ * /aas/submodels/{subModelId}/operations/{operationId} Deletes a specific
+ * Operation from the AAS's Submodel<br />
+ * /aas/submodels/{subModelId}/events/{eventId} Deletes a specific event from
+ * the AAS's submodel
+ * <br /><br />
+ * - setModelPropertyValue<br />
+ * /aas/submodels/{subModelId}/properties/{propertyId} Sets the value of the
+ * AAS's Submodel's Property
+ * 
+ * 
+ * @author kuhn, pschorn
+ *
+ */
+public class MultiSubmodelProvider implements IModelProvider {
+
+	/**
+	 * Store aas providers
+	 */
+	protected AASModelProvider aas_provider = null;
+	
+	/**
+	 * Store aasId
+	 */
+	protected IIdentifier aasId = null;
+
+	/**
+	 * Store submodel providers
+	 */
+	protected Map<String, SubmodelProvider> submodel_providers = new HashMap<>();
+	
+	/**
+	 * Store AAS Registry
+	 */
+	protected IAASRegistry registry = null;
+	
+	/**
+	 * Store HTTP Connector
+	 */
+	protected IConnectorFactory connectorFactory = null;
+
+	/**
+	 * Store AAS API Provider. By default, uses the VAB API Provider
+	 */
+	protected IAASAPIFactory aasApiProvider;
+
+	/**
+	 * Store Submodel API Provider. By default, uses the VAB Submodel Provider
+	 */
+	protected ISubmodelAPIFactory smApiProvider;
+
+	/**
+	 * Constructor with empty default aas and default VAB APIs
+	 */
+	public MultiSubmodelProvider() {
+		this.aasApiProvider = new VABAASAPIFactory();
+		this.smApiProvider = new VABSubmodelAPIFactory();
+		IAASAPI aasApi = aasApiProvider.getAASApi(new AssetAdministrationShell());
+		setAssetAdministrationShell(new AASModelProvider(aasApi));
+	}
+
+	/**
+	 * Constructor for using custom APIs
+	 */
+	public MultiSubmodelProvider(AASModelProvider contentProvider, IAASAPIFactory aasApiProvider,
+			ISubmodelAPIFactory smApiProvider) {
+		this.aasApiProvider = aasApiProvider;
+		this.smApiProvider = smApiProvider;
+		setAssetAdministrationShell(contentProvider);
+	}
+
+	/**
+	 * Constructor that accepts an AAS
+	 */
+	public MultiSubmodelProvider(AASModelProvider contentProvider) {
+		this.aasApiProvider = new VABAASAPIFactory();
+		this.smApiProvider = new VABSubmodelAPIFactory();
+		// Store content provider
+		setAssetAdministrationShell(contentProvider);
+	}
+
+	/**
+	 * Constructor that accepts Submodel
+	 */
+	public MultiSubmodelProvider(SubmodelProvider contentProvider) {
+		this();
+		// Store content provider
+		addSubmodel(contentProvider);
+	}
+	
+	/**
+	 * Constructor that accepts a registry and a connection provider
+	 * @param registry
+	 * @param provider
+	 */
+	public MultiSubmodelProvider(IAASRegistry registry, IConnectorFactory provider) {
+		this();
+		this.registry = registry;
+		this.connectorFactory = provider;
+	}
+	
+	/**
+	 * Constructor that accepts a registry, a connection provider and API providers
+	 */
+	public MultiSubmodelProvider(AASModelProvider contentProvider, IAASRegistry registry,
+			IConnectorFactory connectorFactory, ISubmodelAPIFactory smApiProvider, IAASAPIFactory aasApiProvider) {
+		this(contentProvider, aasApiProvider, smApiProvider);
+		this.registry = registry;
+		this.connectorFactory = connectorFactory;
+	}
+
+	/**
+	 * Constructor that accepts a aas provider, a registry and a connection provider
+	 * 
+	 * @param contentProvider
+	 * @param registry
+	 * @param provider
+	 */
+	public MultiSubmodelProvider(AASModelProvider contentProvider, IAASRegistry registry, HTTPConnectorFactory provider) {
+		this(contentProvider);
+		this.registry = registry;
+		this.connectorFactory = provider;
+	}
+
+	/**
+	 * Set an AAS for this provider
+	 * 
+	 * @param elementId
+	 *            Element ID
+	 * @param modelContentProvider
+	 *            Model content provider
+	 */
+	@SuppressWarnings("unchecked")
+	public void setAssetAdministrationShell(AASModelProvider modelContentProvider) {
+		// Add model provider
+		aas_provider = modelContentProvider;
+		aasId = AssetAdministrationShell.createAsFacade((Map<String, Object>) modelContentProvider.getValue("")).getIdentification();
+	}
+
+	@SuppressWarnings("unchecked")
+	public void addSubmodel(SubmodelProvider modelContentProvider) {
+		Submodel sm = Submodel.createAsFacade((Map<String, Object>) modelContentProvider.getValue("/"));
+		addSubmodel(sm, modelContentProvider);
+	}
+
+	@SuppressWarnings("unchecked")
+	private void createSubmodel(Object newSM) throws ProviderException {
+		// Adds a new submodel to the registered AAS
+		Submodel sm = Submodel.createAsFacade((Map<String, Object>) newSM);
+
+		ISubmodelAPI smApi = smApiProvider.getSubmodelAPI(sm);
+		addSubmodel(sm, new SubmodelProvider(smApi));
+	}
+
+	private void addSubmodel(Submodel sm, SubmodelProvider modelContentProvider) {
+		String smIdShort = sm.getIdShort();
+		submodel_providers.put(smIdShort, modelContentProvider);
+		aas_provider.createValue("/submodels", sm);
+	}
+
+	/**
+	 * Remove a provider
+	 * 
+	 * @param elementId
+	 *            Element ID
+	 */
+	public void removeProvider(String elementId) {
+		// Remove model provider
+		submodel_providers.remove(elementId);
+	}
+
+	/**
+	 * Get the value of an element
+	 */
+	@Override
+	public Object getValue(String path) throws ProviderException {
+		VABPathTools.checkPathForNull(path);
+		path = VABPathTools.stripSlashes(path);
+		String[] pathElements = VABPathTools.splitPath(path);
+		if (pathElements.length > 0 && pathElements[0].equals("aas")) {
+			if (pathElements.length == 1) {
+				return aas_provider.getValue("");
+			}
+			if (pathElements[1].equals(AssetAdministrationShell.SUBMODELS)) {
+				if (pathElements.length == 2) {
+					return retrieveSubmodels();
+				} else {
+					IModelProvider provider = submodel_providers.get(pathElements[2]);
+
+					if (provider == null) {
+						// Get a model provider for the submodel in the registry
+						provider = getModelProvider(pathElements[2]);
+					}
+					
+					// - Retrieve submodel or property value
+					return provider.getValue(VABPathTools.buildPath(pathElements, 4));
+				}
+			} else {
+				// Handle access to AAS
+				return aas_provider.getValue(VABPathTools.buildPath(pathElements, 1));
+			}
+		} else {
+			return new MalformedRequestException("The request " + path + " is not allowed for this endpoint");
+		}
+	}
+
+	/**
+	 * Retrieves all submodels of the AAS. If there's a registry, remote Submodels
+	 * will also be retrieved.
+	 * 
+	 * @return
+	 * @throws ProviderException
+	 */
+	@SuppressWarnings("unchecked")
+	private Object retrieveSubmodels() throws ProviderException {
+		// Make a list and return all local submodels
+		Collection<Submodel> submodels = new HashSet<>();
+		for (IModelProvider submodel : submodel_providers.values()) {
+			submodels.add(Submodel.createAsFacade((Map<String, Object>) submodel.getValue("")));
+		}
+
+		// Check for remote submodels
+		if (registry != null) {
+			AASDescriptor desc = registry.lookupAAS(aasId);
+			
+			// Get the address of the AAS e.g. http://localhost:8080
+			// This address should be equal to the address of this server
+			String aasEndpoint = desc.getFirstEndpoint();
+			String aasServerURL = getServerURL(aasEndpoint);
+			
+			List<String> localIds = submodels.stream().map(sm -> sm.getIdentification().getId()).collect(Collectors.toList());
+			List<IIdentifier> missingIds = desc.getSubmodelDescriptors().stream().map(d -> d.getIdentifier()).
+					filter(id -> !localIds.contains(id.getId())).collect(Collectors.toList());
+			
+			if(!missingIds.isEmpty()) {
+				List<String> missingEndpoints = missingIds.stream().map(id -> desc.getSubmodelDescriptorFromIdentifierId(id.getId()))
+						.map(smDesc -> smDesc.getFirstEndpoint()).collect(Collectors.toList());
+				
+				// Check if any of the missing Submodels have the same address as the AAS.
+				// This would mean, that the Submodel should be present on the same
+				// server of the AAS but is not
+				
+				// If this error would not be caught here an endless loop would develop
+				// as the registry would be asked for this Submodel and then it would be requested
+				// from this server again, which would ask the registry about it again
+				
+				// Such a situation might originate from a deleted but not unregistered Submodel
+				// or from a manually registered but never pushed Submodel
+				for(String missingEndpoint: missingEndpoints) {
+					if(getServerURL(missingEndpoint).equals(aasServerURL)) {
+						throw new ResourceNotFoundException("The Submodel at Endpoint '" + missingEndpoint + 
+								"' does not exist on this server. It seems to be registered but not actually present.");
+					}
+				}
+				
+				List<Submodel> remoteSms = missingEndpoints.stream().map(endpoint -> connectorFactory.getConnector(endpoint)).
+						map(p -> (Map<String, Object>) p.getValue("")).map(m -> Submodel.createAsFacade(m)).collect(Collectors.toList());
+				submodels.addAll(remoteSms);
+			}
+		}
+
+		return submodels;
+	}
+
+	/**
+	 * Change a model property value
+	 */
+	@Override
+	public void setValue(String path, Object newValue) throws ProviderException {
+ 		VABPathTools.checkPathForNull(path);
+		path = VABPathTools.stripSlashes(path);
+		// Split path
+		String[] pathElements = VABPathTools.splitPath(path);
+		String propertyPath = VABPathTools.buildPath(pathElements, 3);
+		// - Ignore first 2 elements, as it is "/aas/submodels" --> 'aas','submodels'
+		
+		if (path.equals("aas")) {
+			createAssetAdministrationShell(newValue);
+		} else if (!path.startsWith("aas/submodels")) {
+			throw new MalformedRequestException("Access to MultiSubmodelProvider always has to start with \"aas/submodels\", was " + path);
+		} else if (propertyPath.isEmpty()) {
+			createSubmodel(newValue);
+		} else {
+			IModelProvider provider;
+			if (isSubmodelLocal(pathElements[2])) {
+				provider = submodel_providers.get(pathElements[2]);
+			} else {
+				// Get a model provider for the submodel in the registry
+				provider = getModelProvider(pathElements[2]);
+			}
+			provider.setValue(propertyPath, newValue);
+		}
+	}
+
+	@Override
+	public void createValue(String path, Object newValue) throws ProviderException {
+		throw new MalformedRequestException("Create is not supported by VABMultiSubmodelProvider. Path was: " + path);
+	}
+
+
+	@SuppressWarnings("unchecked")
+	private void createAssetAdministrationShell(Object newAAS) {
+		Map<String, Object> aas = (Map<String, Object>) newAAS;
+		AssetAdministrationShell shell = AssetAdministrationShell.createAsFacade(aas);
+		IAASAPI aasApi = aasApiProvider.getAASApi(shell);
+		aas_provider = new AASModelProvider(aasApi);
+	}
+
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public void deleteValue(String path) throws ProviderException {
+		VABPathTools.checkPathForNull(path);
+		path = VABPathTools.stripSlashes(path);
+		String[] pathElements = VABPathTools.splitPath(path);
+		String propertyPath = VABPathTools.buildPath(pathElements, 3);
+		// - Ignore first 2 elements, as it is "/aas/submodels" --> 'aas','submodels'
+		if (pathElements.length == 3) {
+			// Delete Submodel from registered AAS
+			String smIdShort = pathElements[2];
+			if (!isSubmodelLocal(smIdShort)) {
+				return;	
+			}
+
+			// Delete submodel reference from aas
+			// TODO: This is a hack until the API is further clarified
+			Submodel sm = Submodel.createAsFacade((Map<String, Object>) submodel_providers.get(smIdShort).getValue("/"));
+			aas_provider.deleteValue("aas/submodels/" + sm.getIdentification().getId());
+
+			// Remove submodel provider
+			submodel_providers.remove(smIdShort);
+		} else if (propertyPath.length() > 0) {
+			IModelProvider provider;
+			if (isSubmodelLocal(pathElements[2])) {
+				provider = submodel_providers.get(pathElements[2]);
+			} else {
+				// Get a model provider for the submodel in the registry
+				provider = getModelProvider(pathElements[2]);
+			}
+
+			provider.deleteValue(propertyPath);
+		}
+	}
+
+	@Override
+	public void deleteValue(String path, Object obj) throws ProviderException {
+		throw new MalformedRequestException("DeleteValue with a parameter is not supported. Path was: " + path);
+	}
+
+	@Override
+	public Object invokeOperation(String path, Object... parameter) throws ProviderException {
+		VABPathTools.checkPathForNull(path);
+		path = VABPathTools.stripSlashes(path);
+		String[] pathElements = VABPathTools.splitPath(path);
+		String operationPath = VABPathTools.buildPath(pathElements, 3);
+		// - Ignore first 2 elements, as it is "/aas/submodels" --> 'aas','submodels'
+		// - Invoke provider and return result
+		IModelProvider provider;
+		if (isSubmodelLocal(pathElements[2])) {
+			provider = submodel_providers.get(pathElements[2]);
+		} else {
+			// Get a model provider for the submodel in the registry
+			provider = getModelProvider(pathElements[2]);
+		}
+
+		return provider.invokeOperation(operationPath, parameter);
+	}
+	
+	/**
+	 * Check whether the given submodel exists in submodel provider
+	 * @param key to search the submodel
+	 * @return boolean true/false
+	 */
+	private boolean isSubmodelLocal(String submodelId) {
+		return submodel_providers.containsKey(submodelId);
+	}
+	
+	/**
+	 * Check whether a registry exists
+	 * @return boolean true/false
+	 */
+	private boolean doesRegistryExist() {
+		return this.registry != null;
+	}
+	
+	/**
+	 * Get submodel descriptor from the registry
+	 * @param submodelId to search the submodel
+	 * @return a specifi submodel descriptor
+	 */
+	private SubmodelDescriptor getSubmodelDescriptorFromRegistry(String submodelIdShort) {
+		AASDescriptor aasDescriptor = registry.lookupAAS(aasId);
+		SubmodelDescriptor desc = aasDescriptor.getSubmodelDescriptorFromIdShort(submodelIdShort);
+		if(desc == null) {
+			throw new ResourceNotFoundException("Could not resolve Submodel with idShort " + submodelIdShort + " for AAS " + aasId);
+		}
+		return desc;
+	}
+	
+	/**
+	 * Get a model provider from a submodel descriptor
+	 * @param submodelDescriptor
+	 * @return a model provider
+	 */
+	private IModelProvider getModelProvider(SubmodelDescriptor submodelDescriptor) {
+		String endpoint = submodelDescriptor.getFirstEndpoint();
+
+		// Remove "/submodel" since it will be readded later
+		endpoint = endpoint.substring(0, endpoint.length() - SubmodelProvider.SUBMODEL.length() - 1);
+
+		return connectorFactory.getConnector(endpoint);
+	}
+	
+	/**
+	 * Get a model provider from a submodel id
+	 * @param submodelId to select a specific submodel
+	 * @throws ResourceNotFoundException if no registry is found
+	 * @return a model provider
+	 */
+	private IModelProvider getModelProvider(String submodelId) {
+		if (!doesRegistryExist()) {
+			throw new ResourceNotFoundException("Submodel with id " + submodelId + " cannot be resolved locally, but no registry is passed");	
+		}
+		
+		SubmodelDescriptor submodelDescriptor = getSubmodelDescriptorFromRegistry(submodelId);
+		return getModelProvider(submodelDescriptor);
+	}
+	
+	/**
+	 * Gets the server URL of a given endpoint.
+	 * e.g. http://localhost:1234/x/y/z/aas/submodels/Sm1IdShort would return
+	 * http://localhost:1234/x/y/z
+	 * 
+	 * @param endpoint
+	 * @return the server URL part of the given endpoint
+	 */
+	public static String getServerURL(String endpoint) {
+		int endServerURL = endpoint.indexOf("/aas");
+		// if indexOf returned -1 ("/aas" not present in String)
+		// return the whole given path
+		if(endServerURL < 0) {
+			return endpoint;
+		}
+		return endpoint.substring(0, endServerURL);
+	}
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/restapi/VABAASAPI.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/restapi/VABAASAPI.java
deleted file mode 100644
index 49f4bc2..0000000
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/restapi/VABAASAPI.java
+++ /dev/null
@@ -1,71 +0,0 @@
-package org.eclipse.basyx.aas.restapi;
-
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
-import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
-import org.eclipse.basyx.aas.restapi.api.IAASAPI;
-import org.eclipse.basyx.submodel.metamodel.api.reference.IKey;
-import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
-import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
-import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
-
-/**
- * Implements the AAS API by mapping it to the VAB
- * 
- * @author schnicke
- *
- */
-public class VABAASAPI implements IAASAPI {
-
-	// The VAB model provider containing the model this API implementation is based
-	// on
-	private IModelProvider provider;
-
-	/**
-	 * Creates a VABAASAPI that wraps an IModelProvider
-	 * 
-	 * @param modelProvider
-	 *            providing the AAS
-	 */
-	public VABAASAPI(IModelProvider provider) {
-		super();
-		this.provider = provider;
-	}
-
-	@SuppressWarnings("unchecked")
-	@Override
-	public IAssetAdministrationShell getAAS() {
-		// For access on the container property root, return the whole model
-		Map<String, Object> map = (Map<String, Object>) provider.getModelPropertyValue("");
-		return AssetAdministrationShell.createAsFacade(map);
-	}
-
-	@Override
-	public void addSubmodel(IReference submodel) {
-		provider.createValue(AssetAdministrationShell.SUBMODELS, submodel);
-	}
-	
-	@SuppressWarnings("unchecked")
-	@Override
-	public void removeSubmodel(String id) {
-		Collection<Map<String, Object>> smReferences = (Collection<Map<String, Object>>) provider.getModelPropertyValue(AssetAdministrationShell.SUBMODELS);
-		// Reference to submodel could be either by idShort (=> local) or directly via
-		// its identifier
-		for (Iterator<Map<String, Object>> iterator = smReferences.iterator(); iterator.hasNext();) {
-			Map<String, Object> smRefMap = iterator.next();
-			IReference ref = Reference.createAsFacade(smRefMap);
-			List<IKey> keys = ref.getKeys();
-			IKey lastKey = keys.get(keys.size() - 1);
-			String idValue = lastKey.getValue();
-			// remove this reference, if the last key points to the submodel
-			if (idValue.equals(id)) {
-				provider.deleteValue(AssetAdministrationShell.SUBMODELS, ref);
-				break;
-			}
-		}
-	}
-}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/restapi/VABMultiSubmodelProvider.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/restapi/VABMultiSubmodelProvider.java
deleted file mode 100644
index c4a401a..0000000
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/restapi/VABMultiSubmodelProvider.java
+++ /dev/null
@@ -1,286 +0,0 @@
-package org.eclipse.basyx.aas.restapi;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-
-import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
-import org.eclipse.basyx.submodel.restapi.SubModelProvider;
-import org.eclipse.basyx.vab.exception.provider.ProviderException;
-import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
-import org.eclipse.basyx.vab.modelprovider.VABPathTools;
-import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
-
-/**
- * Provider class that implements the AssetAdministrationShellServices <br />
- * This provider supports operations on multiple sub models that are selected by
- * path<br />
- * <br />
- * Supported API:<br />
- * - getModelPropertyValue<br />
- * /aas Returns the Asset Administration Shell<br />
- * /aas/submodels Retrieves all SubModels from the current Asset Administration
- * Shell<br />
- * /aas/submodels/{subModelId} Retrieves a specific SubModel from a specific
- * Asset Administration Shell<br />
- * /aas/submodels/{subModelId}/properties Retrieves all Properties from the
- * current SubModel<br />
- * /aas/submodels/{subModelId}/operations Retrieves all Operations from the
- * current SubModel<br />
- * /aas/submodels/{subModelId}/events Retrieves all Events from the current
- * SubModel<br />
- * /aas/submodels/{subModelId}/properties/{propertyId} Retrieves a specific
- * property from the AAS's SubModel<br />
- * /aas/submodels/{subModelId}/operations/{operationId} Retrieves a specific
- * Operation from the AAS's SubModel<br />
- * /aas/submodels/{subModelId}/events/{eventId} Retrieves a specific event from
- * the AAS's submodel
- * <br /><br />
- * - createValue <br />
- * /aas/submodels Adds a new SubModel to an existing Asset Administration Shell
- * <br /><br />
- * /aas/submodels/{subModelId}/properties Adds a new property to the AAS's
- * submodel <br />
- * /aas/submodels/{subModelId}/operations Adds a new operation to the AAS's
- * submodel <br />
- * /aas/submodels/{subModelId}/events Adds a new event to the AAS's submodel
- * <br /><br />
- * - invokeOperation<br />
- * /aas/submodels/{subModelId}/operations/{operationId} Invokes a specific
- * operation from the AAS' submodel with a list of input parameters
- * <br /><br />
- * - deleteValue<br />
- * /aas/submodels/{subModelId} Deletes a specific SubModel from a specific Asset
- * Administration Shell <br />
- * /aas/submodels/{subModelId}/properties/{propertyId} Deletes a specific
- * Property from the AAS's SubModel<br />
- * /aas/submodels/{subModelId}/operations/{operationId} Deletes a specific
- * Operation from the AAS's SubModel<br />
- * /aas/submodels/{subModelId}/events/{eventId} Deletes a specific event from
- * the AAS's submodel
- * <br /><br />
- * - setModelPropertyValue<br />
- * /aas/submodels/{subModelId}/properties/{propertyId} Sets the value of the
- * AAS's SubModel's Property
- * 
- * 
- * @author kuhn, pschorn
- *
- */
-public class VABMultiSubmodelProvider implements IModelProvider {
-
-	/**
-	 * Store aas providers
-	 */
-	protected AASModelProvider aas_provider = null;
-
-	/**
-	 * Store submodel providers
-	 */
-	protected Map<String, SubModelProvider> submodel_providers = new HashMap<>();
-
-	/**
-	 * Constructor
-	 */
-	public VABMultiSubmodelProvider() {
-		this(new AASModelProvider(new AssetAdministrationShell()));
-	}
-
-	/**
-	 * Constructor that accepts an AAS
-	 */
-	public VABMultiSubmodelProvider(AASModelProvider contentProvider) {
-		// Store content provider
-		setAssetAdministrationShell(contentProvider);
-	}
-
-	/**
-	 * Constructor that accepts Submodel
-	 */
-	public VABMultiSubmodelProvider(String smID, SubModelProvider contentProvider) {
-		this();
-		// Store content provider
-		addSubmodel(smID, contentProvider);
-	}
-
-	/**
-	 * Set an AAS for this provider
-	 * 
-	 * @param elementId
-	 *            Element ID
-	 * @param modelContentProvider
-	 *            Model content provider
-	 */
-	public void setAssetAdministrationShell(AASModelProvider modelContentProvider) {
-		// Add model provider
-		aas_provider = modelContentProvider;
-	}
-
-	/**
-	 * Add a Submodel to the provider
-	 * 
-	 * @param elementId
-	 *            Element ID
-	 * @param modelContentProvider
-	 *            Model content provider
-	 */
-	@SuppressWarnings("unchecked")
-	public void addSubmodel(String elementId, SubModelProvider modelContentProvider) {
-		// Add model provider
-		submodel_providers.put(elementId, modelContentProvider);
-
-		SubModel sm = SubModel.createAsFacade((Map<String, Object>) modelContentProvider.getModelPropertyValue("/"));
-
-		// Adds a new submodel to the registered AAS
-		aas_provider.createValue("/submodels", sm);
-	}
-
-	/**
-	 * Remove a provider
-	 * 
-	 * @param elementId
-	 *            Element ID
-	 */
-	public void removeProvider(String elementId) {
-		// Remove model provider
-		submodel_providers.remove(elementId);
-	}
-
-	/**
-	 * Get the value of an element
-	 */
-	@Override
-	public Object getModelPropertyValue(String path) throws ProviderException {
-		VABPathTools.checkPathForNull(path);
-		String[] pathElements = VABPathTools.splitPath(path);
-		if (pathElements.length == 0) { // e.g. "/"
-			return null;
-		} else if (pathElements[0].equals("aas")) {
-			if (pathElements.length == 1) {
-				return aas_provider.getModelPropertyValue("");
-			}
-			if (pathElements[1].equals(AssetAdministrationShell.SUBMODELS)) {
-				if (pathElements.length == 2) {
-					// Make a list and return all submodels
-					Collection<Object> submodels = new HashSet<>();
-					for (IModelProvider submodel : submodel_providers.values()) {
-						submodels.add(submodel.getModelPropertyValue(""));
-					}
-					return submodels;
-				} else {
-					IModelProvider hashmapProvider = submodel_providers.get(pathElements[2]);
-
-					if(hashmapProvider == null) {
-						throw new ResourceNotFoundException("Submodel with id " + pathElements[2] + " does not exist");
-					}
-					
-					// - Retrieve submodel or property value
-					return hashmapProvider.getModelPropertyValue(VABPathTools.buildPath(pathElements, 3));
-				}
-			} else {
-				// Handle access to AAS
-				return aas_provider.getModelPropertyValue(VABPathTools.buildPath(pathElements, 1));
-			}
-		} else {
-			return null;
-		}
-	}
-
-	/**
-	 * Change a model property value
-	 */
-	@Override
-	public void setModelPropertyValue(String path, Object newValue) throws ProviderException {
-		VABPathTools.checkPathForNull(path);
-		// Split path
-		String[] pathElements = VABPathTools.splitPath(path);
-		String propertyPath = VABPathTools.buildPath(pathElements, 3);
-		// - Ignore first 2 elements, as it is "/aas/submodels" --> 'aas','submodels'
-		submodel_providers.get(pathElements[2]).setModelPropertyValue(propertyPath, newValue);
-	}
-
-	@Override
-	public void createValue(String path, Object newValue) throws ProviderException {
-		VABPathTools.checkPathForNull(path);
-		String[] pathElements = VABPathTools.splitPath(path);
-		if (pathElements.length >= 1 && pathElements[0].equals("aas")) {
-			if (pathElements.length == 1) {
-				createAssetAdministrationShell(newValue);
-			} else if (pathElements[1].equals(AssetAdministrationShell.SUBMODELS)) {
-				if (pathElements.length == 2) {
-					createSubModel(newValue);
-				} else {
-					String propertyPath = VABPathTools.buildPath(pathElements, 3);
-					createSubModelProperty(pathElements[2], propertyPath, newValue);
-				}
-			}
-		}
-	}
-
-	private void createSubModelProperty(String smId, String propertyPath, Object newProperty) throws ProviderException {
-		SubModelProvider subModelProvider = submodel_providers.get(smId);
-		subModelProvider.createValue(propertyPath, newProperty);
-	}
-
-	@SuppressWarnings("unchecked")
-	private void createAssetAdministrationShell(Object newAAS) {
-		Map<String, Object> aas = (Map<String, Object>) newAAS;
-		aas_provider = new AASModelProvider(AssetAdministrationShell.createAsFacade(aas));
-	}
-
-	@SuppressWarnings("unchecked")
-	private void createSubModel(Object newSM) throws ProviderException {
-		// Adds a new submodel to the registered AAS
-		SubModel sm = SubModel.createAsFacade((Map<String, Object>) newSM);
-
-		addSubmodel(sm.getIdShort(), new SubModelProvider(sm));
-	}
-
-
-	@SuppressWarnings("unchecked")
-	@Override
-	public void deleteValue(String path) throws ProviderException {
-		VABPathTools.checkPathForNull(path);
-		String[] pathElements = VABPathTools.splitPath(path);
-		String propertyPath = VABPathTools.buildPath(pathElements, 3);
-		// - Ignore first 2 elements, as it is "/aas/submodels" --> 'aas','submodels'
-		if (pathElements.length == 3) {
-			// Delete Submodel from registered AAS
-			String smIdShort = pathElements[2];
-			if (!submodel_providers.containsKey(smIdShort)) {
-				return;
-			}
-
-			// Delete submodel reference from aas
-			// TODO: This is a hack until the API is further clarified
-			SubModel sm = SubModel.createAsFacade((Map<String, Object>) submodel_providers.get(smIdShort).getModelPropertyValue("/"));
-			aas_provider.deleteValue("aas/submodels/" + sm.getIdentification().getId());
-
-			// Remove submodel provider
-			submodel_providers.remove(smIdShort);
-		} else if (propertyPath.length() > 0) {
-			submodel_providers.get(pathElements[2]).deleteValue(propertyPath);
-		}
-	}
-
-	@Override
-	public void deleteValue(String path, Object obj) throws ProviderException {
-		VABPathTools.checkPathForNull(path);
-		String[] pathElements = VABPathTools.splitPath(path);
-		String propertyPath = VABPathTools.buildPath(pathElements, 3);
-		// - Ignore first 2 elements, as it is "/aas/submodels" --> 'aas','submodels'
-		submodel_providers.get(pathElements[2]).deleteValue(propertyPath, obj);
-	}
-
-	@Override
-	public Object invokeOperation(String path, Object... parameter) throws ProviderException {
-		VABPathTools.checkPathForNull(path);
-		String[] pathElements = VABPathTools.splitPath(path);
-		String operationPath = VABPathTools.buildPath(pathElements, 3);
-		// - Ignore first 2 elements, as it is "/aas/submodels" --> 'aas','submodels'
-		// - Invoke provider and return result
-		return submodel_providers.get(pathElements[2]).invokeOperation(operationPath, parameter);
-	}
-}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/restapi/api/IAASAPI.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/restapi/api/IAASAPI.java
index fbd03a9..96498fb 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/restapi/api/IAASAPI.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/restapi/api/IAASAPI.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.aas.restapi.api;
 
 import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/restapi/api/IAASAPIFactory.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/restapi/api/IAASAPIFactory.java
new file mode 100644
index 0000000..430a077
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/restapi/api/IAASAPIFactory.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.aas.restapi.api;
+
+import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+
+/**
+ * Interface for providing an AAS API
+ * 
+ * @author espen
+ *
+ */
+public interface IAASAPIFactory {
+	/**
+	 * Return a constructed AAS API based on a raw model provider
+	 * 
+	 * @return
+	 */
+	public IAASAPI getAASApi(AssetAdministrationShell aas);
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/restapi/vab/VABAASAPI.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/restapi/vab/VABAASAPI.java
new file mode 100644
index 0000000..d6e0437
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/restapi/vab/VABAASAPI.java
@@ -0,0 +1,80 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.aas.restapi.vab;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+import org.eclipse.basyx.aas.restapi.api.IAASAPI;
+import org.eclipse.basyx.submodel.metamodel.api.reference.IKey;
+import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
+import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
+
+/**
+ * Implements the AAS API by mapping it to the VAB
+ * 
+ * @author schnicke
+ *
+ */
+public class VABAASAPI implements IAASAPI {
+
+	// The VAB model provider containing the model this API implementation is based
+	// on
+	private IModelProvider provider;
+
+	/**
+	 * Creates a VABAASAPI that wraps an IModelProvider
+	 * 
+	 * @param modelProvider
+	 *            providing the AAS
+	 */
+	public VABAASAPI(IModelProvider provider) {
+		super();
+		this.provider = provider;
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public IAssetAdministrationShell getAAS() {
+		// For access on the container property root, return the whole model
+		Map<String, Object> map = (Map<String, Object>) provider.getValue("");
+		return AssetAdministrationShell.createAsFacade(map);
+	}
+
+	@Override
+	public void addSubmodel(IReference submodel) {
+		provider.createValue(AssetAdministrationShell.SUBMODELS, submodel);
+	}
+	
+	@SuppressWarnings("unchecked")
+	@Override
+	public void removeSubmodel(String id) {
+		Collection<Map<String, Object>> smReferences = (Collection<Map<String, Object>>) provider.getValue(AssetAdministrationShell.SUBMODELS);
+		// Reference to submodel could be either by idShort (=> local) or directly via
+		// its identifier
+		for (Iterator<Map<String, Object>> iterator = smReferences.iterator(); iterator.hasNext();) {
+			Map<String, Object> smRefMap = iterator.next();
+			IReference ref = Reference.createAsFacade(smRefMap);
+			List<IKey> keys = ref.getKeys();
+			IKey lastKey = keys.get(keys.size() - 1);
+			String idValue = lastKey.getValue();
+			// remove this reference, if the last key points to the submodel
+			if (idValue.equals(id)) {
+				provider.deleteValue(AssetAdministrationShell.SUBMODELS, ref);
+				break;
+			}
+		}
+	}
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/restapi/vab/VABAASAPIFactory.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/restapi/vab/VABAASAPIFactory.java
new file mode 100644
index 0000000..c125080
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/restapi/vab/VABAASAPIFactory.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.aas.restapi.vab;
+
+import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+import org.eclipse.basyx.aas.restapi.api.IAASAPI;
+import org.eclipse.basyx.aas.restapi.api.IAASAPIFactory;
+import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaProvider;
+
+/**
+ * AAS API provider that provides the default VAB AAS API
+ * 
+ * @author espen
+ */
+public class VABAASAPIFactory implements IAASAPIFactory {
+	@Override
+	public IAASAPI getAASApi(AssetAdministrationShell aas) {
+		return new VABAASAPI(new VABLambdaProvider(aas));
+	}
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/extensions/aas/aggregator/mqtt/MqttAASAggregator.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/extensions/aas/aggregator/mqtt/MqttAASAggregator.java
new file mode 100644
index 0000000..bc8ca22
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/extensions/aas/aggregator/mqtt/MqttAASAggregator.java
@@ -0,0 +1,123 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.extensions.aas.aggregator.mqtt;
+
+import java.util.Collection;
+
+import org.eclipse.basyx.aas.aggregator.api.IAASAggregator;
+import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+import org.eclipse.basyx.extensions.shared.mqtt.MqttEventService;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
+import org.eclipse.paho.client.mqttv3.MqttClient;
+import org.eclipse.paho.client.mqttv3.MqttException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Implementation variant for the AASAggregator that triggers MQTT events for
+ * different operations on the aggregator. Has to be based on a backend
+ * implementation of the IAASAggregator to forward its method calls.
+ * 
+ * @author haque
+ *
+ */
+public class MqttAASAggregator extends MqttEventService implements IAASAggregator {
+	private static Logger logger = LoggerFactory.getLogger(MqttAASAggregator.class);
+
+	// List of topics
+	public static final String TOPIC_CREATEAAS = "BaSyxAggregator_createdAAS";
+	public static final String TOPIC_DELETEAAS = "BaSyxAggregator_deletedAAS";
+	public static final String TOPIC_UPDATEAAS = "BaSyxAggregator_updatedAAS";
+
+	// The underlying AASAggregator
+	protected IAASAggregator observedAASAggregator;
+	
+	/**
+	 * Constructor for adding this MQTT extension on top of an AASAggregator
+	 * 
+	 * @param observedRegistryService the underlying AAS Aggregator 
+	 * @param serverEndpoint endpoint of mqtt broker
+	 * @param clientId unique client identifier
+	 * @throws MqttException
+	 */
+	public MqttAASAggregator(IAASAggregator observedAASAggregator, String serverEndpoint, String clientId) throws MqttException {
+		super(serverEndpoint, clientId);
+		logger.info("Create new MQTT AAS Aggregator for endpoint " + serverEndpoint);
+		this.observedAASAggregator = observedAASAggregator;
+	}
+
+	/**
+	 * Constructor for adding this MQTT extension on top of an AASAggregator
+	 * 
+	 * @param observedRegistryService the underlying AAS Aggregator 
+	 * @param serverEndpoint endpoint of mqtt broker
+	 * @param clientId unique client identifier
+	 * @param user username for authentication with broker
+	 * @param pw password for authentication with broker
+	 * @throws MqttException
+	 */
+	public MqttAASAggregator(IAASAggregator observedAASAggregator, String serverEndpoint, String clientId, String user, char[] pw)
+			throws MqttException {
+		super(serverEndpoint, clientId, user, pw);
+		logger.info("Create new MQTT AAS Aggregator for endpoint " + serverEndpoint);
+		this.observedAASAggregator = observedAASAggregator;
+	}
+	
+	/**
+	 * Constructor for adding this MQTT extension on top of an AASAggregator
+	 * 
+	 * @param observedRegistryService the underlying AAS Aggregator 
+	 * @param client already configured client
+	 * @throws MqttException
+	 */
+	public MqttAASAggregator(IAASAggregator observedAASAggregator, MqttClient client) throws MqttException {
+		super(client);
+		logger.info("Create new MQTT AAS Aggregator for endpoint " + client.getServerURI());
+		this.observedAASAggregator = observedAASAggregator;
+	}
+	
+	@Override
+	public Collection<IAssetAdministrationShell> getAASList() {
+		return this.observedAASAggregator.getAASList();
+	}
+
+	@Override
+	public IAssetAdministrationShell getAAS(IIdentifier aasId) throws ResourceNotFoundException {
+		return this.observedAASAggregator.getAAS(aasId);
+	}
+
+	@Override
+	public IModelProvider getAASProvider(IIdentifier aasId) throws ResourceNotFoundException {
+		return this.observedAASAggregator.getAASProvider(aasId);
+	}
+
+	@Override
+	public void createAAS(AssetAdministrationShell aas) {
+		this.observedAASAggregator.createAAS(aas);
+		sendMqttMessage(TOPIC_CREATEAAS, aas.getIdentification().getId());
+		
+	}
+
+	@Override
+	public void updateAAS(AssetAdministrationShell aas) throws ResourceNotFoundException {
+		this.observedAASAggregator.updateAAS(aas);
+		sendMqttMessage(TOPIC_UPDATEAAS, aas.getIdentification().getId());
+		
+	}
+
+	@Override
+	public void deleteAAS(IIdentifier aasId) {
+		this.observedAASAggregator.deleteAAS(aasId);
+		sendMqttMessage(TOPIC_DELETEAAS, aasId.getId());
+	}
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/api/IAASTaggedDirectory.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/api/IAASTaggedDirectory.java
index c4ee5b4..795f6a9 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/api/IAASTaggedDirectory.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/api/IAASTaggedDirectory.java
@@ -1,8 +1,17 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.extensions.aas.directory.tagged.api;
 
 import java.util.Set;
 
-import org.eclipse.basyx.aas.registration.api.IAASRegistryService;
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
 
 /**
  * A tagged directory is a registry that allows to register AAS and associate
@@ -11,7 +20,7 @@
  * @author schnicke
  *
  */
-public interface IAASTaggedDirectory extends IAASRegistryService {
+public interface IAASTaggedDirectory extends IAASRegistry {
 	public void register(TaggedAASDescriptor descriptor);
 
 	/**
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/api/TaggedAASDescriptor.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/api/TaggedAASDescriptor.java
index 6c836f2..beae4f2 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/api/TaggedAASDescriptor.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/api/TaggedAASDescriptor.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.extensions.aas.directory.tagged.api;
 
 import java.util.Collection;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/map/MapTaggedDirectory.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/map/MapTaggedDirectory.java
index 47bd26f..403cfba 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/map/MapTaggedDirectory.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/map/MapTaggedDirectory.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.extensions.aas.directory.tagged.map;
 
 import java.util.HashSet;
@@ -7,7 +16,8 @@
 import java.util.stream.Collectors;
 
 import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
-import org.eclipse.basyx.aas.registration.memory.MapRegistry;
+import org.eclipse.basyx.aas.registration.memory.AASRegistry;
+import org.eclipse.basyx.aas.registration.memory.MapRegistryHandler;
 import org.eclipse.basyx.extensions.aas.directory.tagged.api.IAASTaggedDirectory;
 import org.eclipse.basyx.extensions.aas.directory.tagged.api.TaggedAASDescriptor;
 import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
@@ -19,8 +29,7 @@
  * @author schnicke
  *
  */
-public class MapTaggedDirectory extends MapRegistry implements IAASTaggedDirectory {
-
+public class MapTaggedDirectory extends AASRegistry implements IAASTaggedDirectory {
 	private Map<String, Set<TaggedAASDescriptor>> tagMap;
 
 	/**
@@ -31,7 +40,7 @@
 	 * @param tagMap
 	 */
 	public MapTaggedDirectory(Map<String, AASDescriptor> rootMap, Map<String, Set<TaggedAASDescriptor>> tagMap) {
-		super(rootMap);
+		super(new MapRegistryHandler(rootMap));
 		this.tagMap = tagMap;
 	}
 
@@ -72,7 +81,7 @@
 	@Override
 	public void delete(IIdentifier aasIdentifier) {
 		// Let MapRegistry take care of the registry part and only manage the tags
-		AASDescriptor desc = descriptorMap.get(aasIdentifier.getId());
+		AASDescriptor desc = super.lookupAAS(aasIdentifier);
 		super.delete(aasIdentifier);
 
 		if (desc instanceof TaggedAASDescriptor) {
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/proxy/TaggedDirectoryProxy.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/proxy/TaggedDirectoryProxy.java
index 4ddb6cd..293b0c5 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/proxy/TaggedDirectoryProxy.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/proxy/TaggedDirectoryProxy.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.extensions.aas.directory.tagged.proxy;
 
 import java.util.Collection;
@@ -53,7 +62,7 @@
 
 	@SuppressWarnings("unchecked")
 	private Set<TaggedAASDescriptor> performTagRequest(String tagList) {
-		Collection<Map<String, Object>> desc = (Collection<Map<String, Object>>) taggedProvider.getModelPropertyValue(TaggedDirectoryProvider.API_ACCESS + tagList);
+		Collection<Map<String, Object>> desc = (Collection<Map<String, Object>>) taggedProvider.getValue(TaggedDirectoryProvider.API_ACCESS + tagList);
 		return desc.stream().map(m -> TaggedAASDescriptor.createAsFacade(m)).collect(Collectors.toSet());
 	}
 
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/restapi/TaggedDirectoryProvider.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/restapi/TaggedDirectoryProvider.java
index b1238c9..c6d251e 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/restapi/TaggedDirectoryProvider.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/restapi/TaggedDirectoryProvider.java
@@ -1,18 +1,28 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.extensions.aas.directory.tagged.restapi;
 
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Set;
+import java.util.regex.Pattern;
 import java.util.stream.Collectors;
 
-import org.eclipse.basyx.aas.registration.restapi.DirectoryModelProvider;
+import org.eclipse.basyx.aas.registration.restapi.AASRegistryModelProvider;
 import org.eclipse.basyx.extensions.aas.directory.tagged.api.TaggedAASDescriptor;
 import org.eclipse.basyx.extensions.aas.directory.tagged.map.MapTaggedDirectory;
 import org.eclipse.basyx.vab.exception.provider.ProviderException;
 import org.eclipse.basyx.vab.modelprovider.VABPathTools;
 
-public class TaggedDirectoryProvider extends DirectoryModelProvider {
+public class TaggedDirectoryProvider extends AASRegistryModelProvider {
 	private MapTaggedDirectory directory;
 	public static final String PREFIX = "api/v1/directory";
 	public static final String API_ACCESS = "?tags=";
@@ -27,12 +37,12 @@
 	}
 
 	@Override
-	public Object getModelPropertyValue(String path) throws ProviderException {
+	public Object getValue(String path) throws ProviderException {
 		path = VABPathTools.stripSlashes(path);
 		if (path.startsWith(PREFIX)) {
 			return directory.lookupTags(extractTags(path));
 		} else {
-			return super.getModelPropertyValue(path);
+			return super.getValue(path);
 		}
 	}
 	
@@ -49,10 +59,10 @@
 
 	private Set<String> extractTags(String path) {
 		path = VABPathTools.stripSlashes(path);
-		path = path.replace(PREFIX, "");
+		path = path.replaceFirst(PREFIX, "");
 
 		// Paths now does only contain ?tags=a,b,c
-		path = path.replace(API_ACCESS, "");
+		path = path.replaceFirst(Pattern.quote(API_ACCESS), "");
 		return Arrays.stream(path.split(",")).collect(Collectors.toSet());
 	}
 
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/extensions/aas/registration/mqtt/MqttAASRegistryService.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/extensions/aas/registration/mqtt/MqttAASRegistryService.java
new file mode 100644
index 0000000..4181c5e
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/extensions/aas/registration/mqtt/MqttAASRegistryService.java
@@ -0,0 +1,137 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.extensions.aas.registration.mqtt;
+
+import java.util.List;
+
+import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
+import org.eclipse.basyx.extensions.shared.mqtt.MqttEventService;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.vab.exception.provider.ProviderException;
+import org.eclipse.paho.client.mqttv3.MqttClient;
+import org.eclipse.paho.client.mqttv3.MqttException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Implementation variant for the AASRegistryService that triggers MQTT events for
+ * different operations on the registry. Has to be based on a backend
+ * implementation of the IAASRegistryService to forward its method calls.
+ * 
+ * @author haque
+ *
+ */
+public class MqttAASRegistryService extends MqttEventService implements IAASRegistry {
+	private static Logger logger = LoggerFactory.getLogger(MqttAASRegistryService.class);
+
+	// List of topics
+	public static final String TOPIC_REGISTERAAS = "BaSyxRegistry_registeredAAS";
+	public static final String TOPIC_REGISTERSUBMODEL = "BaSyxRegistry_registeredSubmodel";
+	public static final String TOPIC_DELETEAAS = "BaSyxRegistry_deletedAAS";
+	public static final String TOPIC_DELETESUBMODEL = "BaSyxRegistry_deletedSubmodel";
+
+	// The underlying AASRegistryService
+	protected IAASRegistry observedRegistryService;
+	
+	/**
+	 * Constructor for adding this MQTT extension on top of an AASRegistryService
+	 * 
+	 * @param observedRegistryService the underlying registry service 
+	 * @param serverEndpoint endpoint of mqtt broker
+	 * @param clientId unique client identifier
+	 * @throws MqttException
+	 */
+	public MqttAASRegistryService(IAASRegistry observedRegistryService, String serverEndpoint, String clientId) throws MqttException {
+		super(serverEndpoint, clientId);
+		logger.info("Create new MQTT AAS Registry Service for endpoint " + serverEndpoint);
+		this.observedRegistryService = observedRegistryService;
+	}
+
+	/**
+	 * Constructor for adding this MQTT extension on top of an AASRegistryService
+	 * 
+	 * @param observedRegistryService the underlying registry service 
+	 * @param serverEndpoint endpoint of mqtt broker
+	 * @param clientId unique client identifier
+	 * @param user username for authentication with broker
+	 * @param pw password for authentication with broker
+	 * @throws MqttException
+	 */
+	public MqttAASRegistryService(IAASRegistry observedRegistryService, String serverEndpoint, String clientId, String user, char[] pw)
+			throws MqttException {
+		super(serverEndpoint, clientId, user, pw);
+		logger.info("Create new MQTT AAS Registry Service for endpoint " + serverEndpoint);
+		this.observedRegistryService = observedRegistryService;
+	}
+	
+	/**
+	 * Constructor for adding this MQTT extension on top of an AASRegistryService
+	 * 
+	 * @param observedRegistryService the underlying registry service 
+	 * @param client already configured client
+	 * @throws MqttException
+	 */
+	public MqttAASRegistryService(IAASRegistry observedRegistryService, MqttClient client) throws MqttException {
+		super(client);
+		logger.info("Create new MQTT AAS Registry Service for endpoint " + client.getServerURI());
+		this.observedRegistryService = observedRegistryService;
+	}
+
+	
+	@Override
+	public void register(AASDescriptor deviceAASDescriptor) throws ProviderException {
+		this.observedRegistryService.register(deviceAASDescriptor);
+		sendMqttMessage(TOPIC_REGISTERAAS, deviceAASDescriptor.getIdentifier().getId());	
+	}
+
+	@Override
+	public void register(IIdentifier aas, SubmodelDescriptor smDescriptor) throws ProviderException {
+		this.observedRegistryService.register(aas, smDescriptor);
+		sendMqttMessage(TOPIC_REGISTERSUBMODEL, concatAasSmId(aas, smDescriptor.getIdentifier()));
+	}
+
+	@Override
+	public void delete(IIdentifier aasId) throws ProviderException {
+		this.observedRegistryService.delete(aasId);
+		sendMqttMessage(TOPIC_DELETEAAS, aasId.getId());
+	}
+
+	@Override
+	public void delete(IIdentifier aasId, IIdentifier smId) throws ProviderException {
+		this.observedRegistryService.delete(aasId, smId);
+		sendMqttMessage(TOPIC_DELETESUBMODEL, concatAasSmId(aasId, smId));
+	}
+
+	@Override
+	public AASDescriptor lookupAAS(IIdentifier aasId) throws ProviderException {
+		return this.observedRegistryService.lookupAAS(aasId);
+	}
+
+	@Override
+	public List<AASDescriptor> lookupAll() throws ProviderException {
+		return this.observedRegistryService.lookupAll();
+	}
+
+	@Override
+	public List<SubmodelDescriptor> lookupSubmodels(IIdentifier aasId) throws ProviderException {
+		return this.observedRegistryService.lookupSubmodels(aasId);
+	}
+
+	@Override
+	public SubmodelDescriptor lookupSubmodel(IIdentifier aasId, IIdentifier smId) throws ProviderException {
+		return this.observedRegistryService.lookupSubmodel(aasId, smId);
+	}
+	
+	public static String concatAasSmId(IIdentifier aasId, IIdentifier smId) {
+		return "(" + aasId.getId() + "," + smId.getId() + ")";
+	}
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/extensions/shared/mqtt/MqttEventService.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/extensions/shared/mqtt/MqttEventService.java
new file mode 100644
index 0000000..f71ef77
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/extensions/shared/mqtt/MqttEventService.java
@@ -0,0 +1,116 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.extensions.shared.mqtt;
+
+import org.eclipse.paho.client.mqttv3.MqttClient;
+import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
+import org.eclipse.paho.client.mqttv3.MqttException;
+import org.eclipse.paho.client.mqttv3.MqttMessage;
+import org.eclipse.paho.client.mqttv3.MqttPersistenceException;
+import org.eclipse.paho.client.mqttv3.persist.MqttDefaultFilePersistence;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Implementation of common parts of MQTT event propagation services.
+ * Extend this class to make a service MQTT extendable
+ *  
+ * @author haque
+ *
+ */
+public class MqttEventService {
+	private static Logger logger = LoggerFactory.getLogger(MqttEventService.class);
+
+	// The MQTTClient
+	protected MqttClient mqttClient;
+
+	// QoS for MQTT messages (1, 2 or 3).
+	protected int qos = 1;
+	
+	/**
+	 * Constructor for creating an MqttClient (no authentication)
+	 * @param serverEndpoint
+	 * @param clientId
+	 * @throws MqttException
+	 */
+	public MqttEventService(String serverEndpoint, String clientId) throws MqttException {
+		this.mqttClient = new MqttClient(serverEndpoint, clientId, new MqttDefaultFilePersistence());
+		mqttClient.connect();
+	}
+	
+	/**
+	 * Constructor for creating an MqttClient with authentication
+	 * @param serverEndpoint
+	 * @param clientId
+	 * @param user
+	 * @param pw
+	 * @throws MqttException
+	 */
+	public MqttEventService(String serverEndpoint, String clientId, String user, char[] pw)
+			throws MqttException {
+		this.mqttClient = new MqttClient(serverEndpoint, clientId, new MqttDefaultFilePersistence());
+		MqttConnectOptions options = new MqttConnectOptions();
+		options.setUserName(user);
+		options.setPassword(pw);
+		mqttClient.connect(options);
+	}
+	
+	/**
+	 * Constructor for creating an MqttClient with existing client
+	 * @param client
+	 * @throws MqttException
+	 */
+	public MqttEventService(MqttClient client) throws MqttException {
+		this.mqttClient = client;
+		mqttClient.connect();
+	}
+
+	/**
+	 * Sets the QoS for MQTT messages
+	 * 
+	 * @param qos
+	 */
+	public void setQoS(int qos) {
+		if (qos >= 0 && qos <= 3) {
+			this.qos = qos;
+		} else {
+			throw new IllegalArgumentException("Invalid QoS: " + qos);
+		}
+	}
+
+	/**
+	 * Gets the QoS for MQTT messages
+	 * 
+	 * @param qos
+	 */
+	public int getQoS() {
+		return this.qos;
+	}
+	
+	/**
+	 * Sends MQTT message to connected broker
+	 * @param topic in which the message will be published
+	 * @param payload the actual message
+	 */
+	protected void sendMqttMessage(String topic, String payload) {
+		MqttMessage msg = new MqttMessage(payload.getBytes());
+		if (this.qos != 1) {
+			msg.setQos(this.qos);
+		}
+		try {
+			logger.debug("Send MQTT message to " + topic + ": " + payload);
+			mqttClient.publish(topic, msg);
+		} catch (MqttPersistenceException e) {
+			logger.error("Could not persist mqtt message", e);
+		} catch (MqttException e) {
+			logger.error("Could not send mqtt message", e);
+		}
+	}
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/extensions/submodel/mqtt/MqttSubmodelAPI.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/extensions/submodel/mqtt/MqttSubmodelAPI.java
new file mode 100644
index 0000000..fdf33e9
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/extensions/submodel/mqtt/MqttSubmodelAPI.java
@@ -0,0 +1,231 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.extensions.submodel.mqtt;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.basyx.extensions.shared.mqtt.MqttEventService;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.api.reference.IKey;
+import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperation;
+import org.eclipse.basyx.submodel.restapi.api.ISubmodelAPI;
+import org.eclipse.basyx.vab.modelprovider.VABPathTools;
+import org.eclipse.paho.client.mqttv3.MqttClient;
+import org.eclipse.paho.client.mqttv3.MqttException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Implementation variant for the SubmodelAPI that triggers MQTT events for
+ * different CRUD operations on the submodel. Has to be based on a backend
+ * implementation of the ISubmodelAPI to forward its method calls.
+ * 
+ * @author espen
+ *
+ */
+public class MqttSubmodelAPI extends MqttEventService implements ISubmodelAPI {
+	private static Logger logger = LoggerFactory.getLogger(MqttSubmodelAPI.class);
+
+	// List of topics
+	public static final String TOPIC_CREATESUBMODEL = "BaSyxSubmodel_createdSubmodel";
+	public static final String TOPIC_ADDELEMENT = "BaSyxSubmodel_addedSubmodelElement";
+	public static final String TOPIC_DELETEELEMENT = "BaSyxSubmodel_removedSubmodelElement";
+	public static final String TOPIC_UPDATEELEMENT = "BaSyxSubmodel_updatedSubmodelElement";
+
+	// The underlying SubmodelAPI
+	protected ISubmodelAPI observedAPI;
+
+	// Submodel Element whitelist for filtering
+	protected boolean useWhitelist = false;
+	protected Set<String> whitelist = new HashSet<>();
+
+	/**
+	 * Constructor for adding this MQTT extension on top of another SubmodelAPI
+	 * 
+	 * @param observedAPI The underlying submodelAPI
+	 * @throws MqttException
+	 */
+	public MqttSubmodelAPI(ISubmodelAPI observedAPI, String serverEndpoint, String clientId) throws MqttException {
+		super(serverEndpoint, clientId);
+		logger.info("Create new MQTT submodel for endpoint " + serverEndpoint);
+		this.observedAPI = observedAPI;
+		sendMqttMessage(TOPIC_CREATESUBMODEL, observedAPI.getSubmodel().getIdentification().getId());
+	}
+
+	/**
+	 * Constructor for adding this MQTT extension on top of another SubmodelAPI
+	 * 
+	 * @param observedAPI The underlying submodelAPI
+	 * @throws MqttException
+	 */
+	public MqttSubmodelAPI(ISubmodelAPI observedAPI, String serverEndpoint, String clientId, String user, char[] pw)
+			throws MqttException {
+		super(serverEndpoint, clientId, user, pw);
+		logger.info("Create new MQTT submodel for endpoint " + serverEndpoint);
+		this.observedAPI = observedAPI;
+		sendMqttMessage(TOPIC_CREATESUBMODEL, observedAPI.getSubmodel().getIdentification().getId());
+	}
+
+	/**
+	 * Constructor for adding this MQTT extension on top of another SubmodelAPI.
+	 * 
+	 * @param observedAPI The underlying submodelAPI
+	 * @param client      An already connected mqtt client
+	 * @throws MqttException 
+	 */
+	public MqttSubmodelAPI(ISubmodelAPI observedAPI, MqttClient client) throws MqttException {
+		super(client);
+		this.observedAPI = observedAPI;
+		sendMqttMessage(TOPIC_CREATESUBMODEL, observedAPI.getSubmodel().getIdentification().getId());
+	}
+
+	/**
+	 * Adds a submodel element to the filter whitelist. Can also be a path for nested submodel elements.
+	 * 
+	 * @param element
+	 */
+	public void observeSubmodelElement(String shortId) {
+		whitelist.add(VABPathTools.stripSlashes(shortId));
+	}
+
+	/**
+	 * Sets a new filter whitelist.
+	 * 
+	 * @param element
+	 */
+	public void setWhitelist(Set<String> shortIds) {
+		this.whitelist.clear();
+		for (String entry : shortIds) {
+			this.whitelist.add(VABPathTools.stripSlashes(entry));
+		}
+	}
+
+	/**
+	 * Disables the submodel element filter whitelist
+	 * 
+	 * @param element
+	 */
+	public void disableWhitelist() {
+		useWhitelist = false;
+	}
+
+	/**
+	 * Enables the submodel element filter whitelist
+	 * 
+	 * @param element
+	 */
+	public void enableWhitelist() {
+		useWhitelist = true;
+	}
+
+	@Override
+	public ISubmodel getSubmodel() {
+		return observedAPI.getSubmodel();
+	}
+
+	@Override
+	public void addSubmodelElement(ISubmodelElement elem) {
+		observedAPI.addSubmodelElement(elem);
+		if (filter(elem.getIdShort())) {
+			sendMqttMessage(TOPIC_ADDELEMENT, getCombinedMessage(getAASId(), getSubmodelId(), elem.getIdShort()));
+		}
+	}
+
+	@Override
+	public void addSubmodelElement(String idShortPath, ISubmodelElement elem) {
+		observedAPI.addSubmodelElement(idShortPath, elem);
+		if (filter(idShortPath)) {
+			sendMqttMessage(TOPIC_ADDELEMENT, getCombinedMessage(getAASId(), getSubmodelId(), idShortPath));
+		}
+	}
+
+	@Override
+	public ISubmodelElement getSubmodelElement(String idShortPath) {
+		return observedAPI.getSubmodelElement(idShortPath);
+	}
+
+	@Override
+	public void deleteSubmodelElement(String idShortPath) {
+		observedAPI.deleteSubmodelElement(idShortPath);
+		if (filter(idShortPath)) {
+			sendMqttMessage(TOPIC_DELETEELEMENT, getCombinedMessage(getAASId(), getSubmodelId(), idShortPath));
+		}
+	}
+
+	@Override
+	public Collection<IOperation> getOperations() {
+		return observedAPI.getOperations();
+	}
+
+	@Override
+	public Collection<ISubmodelElement> getSubmodelElements() {
+		return observedAPI.getSubmodelElements();
+	}
+
+	@Override
+	public void updateSubmodelElement(String idShortPath, Object newValue) {
+		observedAPI.updateSubmodelElement(idShortPath, newValue);
+		if (filter(idShortPath)) {
+			sendMqttMessage(TOPIC_UPDATEELEMENT, getCombinedMessage(getAASId(), getSubmodelId(), idShortPath));
+		}
+	}
+
+	@Override
+	public Object getSubmodelElementValue(String idShortPath) {
+		return observedAPI.getSubmodelElementValue(idShortPath);
+	}
+
+	@Override
+	public Object invokeOperation(String idShortPath, Object... params) {
+		return observedAPI.invokeOperation(idShortPath, params);
+	}
+
+	@Override
+	public Object invokeAsync(String idShortPath, Object... params) {
+		return observedAPI.invokeAsync(idShortPath, params);
+	}
+
+	@Override
+	public Object getOperationResult(String idShort, String requestId) {
+		return observedAPI.getOperationResult(idShort, requestId);
+	}
+	
+	public static String getCombinedMessage(String aasId, String submodelId, String elementPart) {
+		elementPart = VABPathTools.stripSlashes(elementPart);
+		return "(" + aasId + "," + submodelId + "," + elementPart + ")";
+	}
+
+	private boolean filter(String idShort) {
+		idShort = VABPathTools.stripSlashes(idShort);
+		return !useWhitelist || whitelist.contains(idShort);
+	}
+	
+	private String getSubmodelId() {
+		ISubmodel submodel = getSubmodel();
+		return submodel.getIdentification().getId();
+	}
+	
+	private String getAASId() {
+		ISubmodel submodel = getSubmodel();
+		IReference parentReference = submodel.getParent();
+		if (parentReference != null) {
+			List<IKey> keys = parentReference.getKeys();
+			if (keys != null && keys.size() > 0) {
+				return keys.get(0).getValue();
+			}
+		}
+		return null;
+	}
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/XMLHelper.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/XMLHelper.java
index e724425..9967865 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/XMLHelper.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/XMLHelper.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.factory.xml;
 
 import java.util.ArrayList;
@@ -45,4 +54,4 @@
 	public static String getString(Object object) {
 		return object instanceof String ? ((String) object).trim() : "";
 	}
-}
\ No newline at end of file
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/api/dataspecification/DataSpecificationIEC61360XMLConverter.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/api/dataspecification/DataSpecificationIEC61360XMLConverter.java
index 855a8ba..f3f52b0 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/api/dataspecification/DataSpecificationIEC61360XMLConverter.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/api/dataspecification/DataSpecificationIEC61360XMLConverter.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.factory.xml.api.dataspecification;
 
 import java.util.ArrayList;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/api/parts/ConceptDescriptionXMLConverter.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/api/parts/ConceptDescriptionXMLConverter.java
index 07532b9..a46f9db 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/api/parts/ConceptDescriptionXMLConverter.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/api/parts/ConceptDescriptionXMLConverter.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.factory.xml.api.parts;
 
 import java.util.ArrayList;
@@ -12,7 +21,10 @@
 import org.eclipse.basyx.submodel.factory.xml.converters.reference.ReferenceXMLConverter;
 import org.eclipse.basyx.submodel.metamodel.api.parts.IConceptDescription;
 import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
 import org.eclipse.basyx.submodel.metamodel.map.parts.ConceptDescription;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasDataSpecification;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Identifiable;
 import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
@@ -44,8 +56,8 @@
 		for (Map<String, Object> xmlConceptDescription : xmlConceptDescriptionList) {
 			ConceptDescription conceptDescription = new ConceptDescription();
 			
-			IdentifiableXMLConverter.populateIdentifiable(xmlConceptDescription, conceptDescription);
-			HasDataSpecificationXMLConverter.populateHasDataSpecification(xmlConceptDescription, conceptDescription);
+			IdentifiableXMLConverter.populateIdentifiable(xmlConceptDescription, Identifiable.createAsFacadeNonStrict(conceptDescription, KeyElements.CONCEPTDESCRIPTION));
+			HasDataSpecificationXMLConverter.populateHasDataSpecification(xmlConceptDescription, HasDataSpecification.createAsFacade(conceptDescription));
 			
 			Collection<Reference> handleIsCaseOf = parseIsCaseOfRefs(xmlConceptDescription);
 			conceptDescription.setIsCaseOf(handleIsCaseOf);
@@ -120,4 +132,4 @@
 			xmlConceptDescription.appendChild(xmlIsCaseOf);
 		}
 	}
-}
\ No newline at end of file
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/SubmodelXMLConverter.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/SubmodelXMLConverter.java
index 8ca4c19..9347f8e 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/SubmodelXMLConverter.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/SubmodelXMLConverter.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.factory.xml.converters;
 
 import java.util.ArrayList;
@@ -12,14 +21,20 @@
 import org.eclipse.basyx.submodel.factory.xml.converters.qualifier.haskind.HasKindXMLConverter;
 import org.eclipse.basyx.submodel.factory.xml.converters.qualifier.qualifiable.QualifiableXMLConverter;
 import org.eclipse.basyx.submodel.factory.xml.converters.submodelelement.SubmodelElementXMLConverter;
-import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
 import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasDataSpecification;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasSemantics;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Identifiable;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.haskind.HasKind;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.qualifiable.Qualifiable;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 
 /**
- * Handles the conversion between ISubModel objects and the XML tag &lt;aas:submodels&gt; in both directions
+ * Handles the conversion between ISubmodel objects and the XML tag &lt;aas:submodels&gt; in both directions
  * 
  * @author conradi
  *
@@ -30,28 +45,28 @@
 	public static final String SUBMODEL = "aas:submodel";
 	
 	/**
-	 * Parses &lt;aas:submodels&gt; and builds the SubModel objects from it
+	 * Parses &lt;aas:submodels&gt; and builds the Submodel objects from it
 	 * 
 	 * @param xmlObject a Map containing the content of the XML tag &lt;aas:submodels&gt;
-	 * @return a List of ISubModel objects parsed form the given XML Map
+	 * @return a List of ISubmodel objects parsed form the given XML Map
 	 */
-	public static List<ISubModel> parseSubmodels(Map<String, Object> xmlObject) {
+	public static List<ISubmodel> parseSubmodels(Map<String, Object> xmlObject) {
 		List<Map<String, Object>> xmlSubmodels = XMLHelper.getList(xmlObject.get(SUBMODEL));
-		List<ISubModel> submodels = new ArrayList<>();
+		List<ISubmodel> submodels = new ArrayList<>();
 		
 		for (Map<String, Object> xmlSubmodel : xmlSubmodels) {
-			SubModel submodel = new SubModel();
+			Submodel submodel = new Submodel();
 			
-			IdentifiableXMLConverter.populateIdentifiable(xmlSubmodel, submodel);
-			HasSemanticsXMLConverter.populateHasSemantics(xmlSubmodel, submodel);
-			HasDataSpecificationXMLConverter.populateHasDataSpecification(xmlSubmodel, submodel);
-			QualifiableXMLConverter.populateQualifiable(xmlSubmodel, submodel);
-			HasKindXMLConverter.populateHasKind(xmlSubmodel, submodel);
+			IdentifiableXMLConverter.populateIdentifiable(xmlSubmodel, Identifiable.createAsFacadeNonStrict(submodel, KeyElements.SUBMODEL));
+			HasSemanticsXMLConverter.populateHasSemantics(xmlSubmodel, HasSemantics.createAsFacade(submodel));
+			HasDataSpecificationXMLConverter.populateHasDataSpecification(xmlSubmodel, HasDataSpecification.createAsFacade(submodel));
+			QualifiableXMLConverter.populateQualifiable(xmlSubmodel, Qualifiable.createAsFacade(submodel));
+			HasKindXMLConverter.populateHasKind(xmlSubmodel, HasKind.createAsFacade(submodel));
 						
 			List<ISubmodelElement> submodelElements = SubmodelElementXMLConverter.parseSubmodelElements(xmlSubmodel);
 						
 			for (ISubmodelElement submdoElement : submodelElements) {
-				submodel.addSubModelElement(submdoElement);
+				submodel.addSubmodelElement(submdoElement);
 			}
 			
 			submodels.add(submodel);
@@ -63,17 +78,17 @@
 	
 	
 	/**
-	 * Builds &lt;aas:submodels&gt; from a given Collection of ISubModel objects
+	 * Builds &lt;aas:submodels&gt; from a given Collection of ISubmodel objects
 	 * 
 	 * @param document the XML document
-	 * @param subModels a Collection of ISubModel objects to build the XML for
-	 * @return the &lt;aas:submodels&gt; XML tag for the given ISubModel objects
+	 * @param subModels a Collection of ISubmodel objects to build the XML for
+	 * @return the &lt;aas:submodels&gt; XML tag for the given ISubmodel objects
 	 */
-	public static Element buildSubmodelsXML(Document document, Collection<ISubModel> subModels) {
+	public static Element buildSubmodelsXML(Document document, Collection<ISubmodel> subModels) {
 		Element root = document.createElement(SUBMODELS);
 		
 		List<Element> xmlSubmodelList = new ArrayList<>();
-		for(ISubModel subModel: subModels) {
+		for(ISubmodel subModel: subModels) {
 			Element subModelRoot = document.createElement(SUBMODEL);
 
 			IdentifiableXMLConverter.populateIdentifiableXML(document, subModelRoot, subModel);
@@ -95,4 +110,4 @@
 		}
 		return root;
 	}
-}
\ No newline at end of file
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/HasDataSpecificationXMLConverter.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/HasDataSpecificationXMLConverter.java
index cd725fe..9eb7956 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/HasDataSpecificationXMLConverter.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/HasDataSpecificationXMLConverter.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.factory.xml.converters.qualifier;
 
 import java.util.ArrayList;
@@ -41,23 +50,25 @@
 	 * @param hasDataSpecificationMap the IHasDataSpecification object to be populated -treated as Map here-
 	 */
 	public static void populateHasDataSpecification(Map<String, Object> xmlObject,
-			Map<String, Object> hasDataSpecificationMap) {
-		HasDataSpecification hasDataSpecification = HasDataSpecification.createAsFacade(hasDataSpecificationMap);
+			HasDataSpecification hasDataSpecification) {
 		if (xmlObject == null || hasDataSpecification == null) return;
 		
 		Object xmlDataSpecObj = xmlObject.get(EMBEDDED_DATA_SPECIFICATION);
-		List<IEmbeddedDataSpecification> embeddedSpecList = new ArrayList<>();
-		List<Map<String, Object>> xmlSpecList = XMLHelper.getList(xmlDataSpecObj);
-		for (Map<String, Object> xmlSpec : xmlSpecList) {
-			IReference ref = parseReference(xmlSpec);
-			IDataSpecificationContent content = parseContent(xmlSpec);
-			EmbeddedDataSpecification spec = new EmbeddedDataSpecification();
-			spec.setDataSpecificationTemplate(ref);
-			// TODO: Also support other templates
-			spec.setContent((DataSpecificationIEC61360Content) content);
-			embeddedSpecList.add(spec);
+		if (xmlDataSpecObj != null ) {
+			List<IEmbeddedDataSpecification> embeddedSpecList = new ArrayList<>();
+			List<Map<String, Object>> xmlSpecList = XMLHelper.getList(xmlDataSpecObj);
+			for (Map<String, Object> xmlSpec : xmlSpecList) {
+				IReference ref = parseReference(xmlSpec);
+				IDataSpecificationContent content = parseContent(xmlSpec);
+				EmbeddedDataSpecification spec = new EmbeddedDataSpecification();
+				spec.setDataSpecificationTemplate(ref);
+				// TODO: Also support other templates
+				spec.setContent((DataSpecificationIEC61360Content) content);
+				embeddedSpecList.add(spec);
+			}
+			hasDataSpecification.setEmbeddedDataSpecifications(embeddedSpecList);	
 		}
-		hasDataSpecification.setEmbeddedDataSpecifications(embeddedSpecList);
+		
 
 		// Note: DataSpecificationReferences are not serialized in XML
 		// "http://admin-shell.io/DataSpecificationTemplates/DataSpecificationIEC61360/2/0" could always be added here,
@@ -135,6 +146,7 @@
 			root.appendChild(embeddedDataSpecRoot);
 		}
 	}
+		
 
 	/**
 	 * Populates a DataSpecificationContent XML from the IDataSpecificationContent object
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/HasSemanticsXMLConverter.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/HasSemanticsXMLConverter.java
index 6f0f55a..b5ea693 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/HasSemanticsXMLConverter.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/HasSemanticsXMLConverter.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.factory.xml.converters.qualifier;
 
 import java.util.Map;
@@ -21,17 +30,17 @@
 	
 
 	/**
-	 * Populates a given IHasSemantics object with the data form the given XML
+	 * Populates a given HasSemantics object with the data form the given XML
 	 * 
 	 * @param xmlObject the XML map containing the &lt;aas:semanticId&gt; tag
-	 * @param hasSemantics the IHasDataSpecification object to be populated -treated as Map here-
+	 * @param hasSemantics the HasSemantics object to be populated
 	 */
 	@SuppressWarnings("unchecked")
-	public static void populateHasSemantics(Map<String, Object> xmlObject, Map<String, Object> hasSemantics) {
-		//The IHasSemantics object has to be treated as Map here, as the Interface has no Setters
-		
+	public static void populateHasSemantics(Map<String, Object> xmlObject, HasSemantics hasSemantics) {
 		Map<String, Object> xmlSemanticIDObj = (Map<String, Object>) xmlObject.get(SEMANTIC_ID);
-		hasSemantics.put(HasSemantics.SEMANTICID, ReferenceXMLConverter.parseReference(xmlSemanticIDObj));
+		if (xmlSemanticIDObj != null) {
+			hasSemantics.setSemanticId(ReferenceXMLConverter.parseReference(xmlSemanticIDObj));
+		}
 	}
 	
 	
@@ -53,4 +62,4 @@
 			root.appendChild(semanticIdRoot);
 		}
 	}
-}
\ No newline at end of file
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/IdentifiableXMLConverter.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/IdentifiableXMLConverter.java
index b87eee1..6dd0fb5 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/IdentifiableXMLConverter.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/IdentifiableXMLConverter.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.factory.xml.converters.qualifier;
 
 import java.util.Map;
@@ -5,12 +14,13 @@
 import org.eclipse.basyx.submodel.factory.xml.XMLHelper;
 import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
 import org.eclipse.basyx.submodel.metamodel.api.qualifier.IIdentifiable;
-import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
 import org.eclipse.basyx.submodel.metamodel.map.qualifier.AdministrativeInformation;
 import org.eclipse.basyx.submodel.metamodel.map.qualifier.Identifiable;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 
+import com.google.common.base.Strings;
+
 /**
  * Handles the conversion between an IIdentifiable object and the XML tags<br>
  * &lt;aas:administration&gt; and &lt;aas:identification&gt; in both directions
@@ -28,36 +38,32 @@
 	
 	
 	/**
-	 * Populates a given IIdentifiable object with the data form the given XML
+	 * Populates a given Identifiable object with the data form the given XML
 	 * 
 	 * @param xmlObject the XML map containing the &lt;aas:administration&gt; and &lt;aas:identification&gt; tags
-	 * @param identifiable the IIdentifiable object to be populated -treated as Map here-
+	 * @param identifiable the Identifiable object to be populated
 	 */
 	@SuppressWarnings("unchecked")
-	public static void populateIdentifiable(Map<String, Object> xmlObject, Map<String, Object> identifiable) {
-		//The IIdentifiable object has to be treated as Map here, as the Interface has no Setters
-		
-		String id="";
-		String idType="";
-		String version="";
-		String revision="";
-		
+	public static void populateIdentifiable(Map<String, Object> xmlObject, Identifiable identifiable) {
 		ReferableXMLConverter.populateReferable(xmlObject, identifiable);
 		
 		Map<String, Object> identierFromXML = (Map<String, Object>) xmlObject.get(IDENTIFICATION);
-		if(identierFromXML != null) {
-			id = XMLHelper.getString(identierFromXML.get(XMLHelper.TEXT));
-			idType = XMLHelper.getString(identierFromXML.get(IDTYPE));
+		if (identierFromXML == null) {
+			throw createInvalidIdentifierException(xmlObject);
 		}
+		String id = XMLHelper.getString(identierFromXML.get(XMLHelper.TEXT));
+		String idType = XMLHelper.getString(identierFromXML.get(IDTYPE));
+		if (Strings.isNullOrEmpty(id) || Strings.isNullOrEmpty(idType)) {
+			throw createInvalidIdentifierException(xmlObject);
+		}
+		identifiable.setIdentification(IdentifierType.fromString(idType), id);
 
-		if(xmlObject.containsKey(ADMINISTRATION)) {
-			Map<String, Object> administrationFromXML = (Map<String, Object>) xmlObject.get(ADMINISTRATION);
-			version = XMLHelper.getString(administrationFromXML.get(VERSION));
-			revision = XMLHelper.getString(administrationFromXML.get(REVISION));	
+		Map<String, Object> administrationFromXML = (Map<String, Object>) xmlObject.get(ADMINISTRATION);
+		if(administrationFromXML != null) {
+			String version = XMLHelper.getString(administrationFromXML.get(VERSION));
+			String revision = XMLHelper.getString(administrationFromXML.get(REVISION));
+			identifiable.setAdministration(new AdministrativeInformation(version, revision));
 		}
-		
-		identifiable.put(Identifiable.ADMINISTRATION, new AdministrativeInformation(version, revision));
-		identifiable.put(Identifiable.IDENTIFICATION, new Identifier(IdentifierType.fromString(idType), id));
 	}
 	
 
@@ -117,4 +123,8 @@
 			}
 		}	
 	}
-}
\ No newline at end of file
+	
+	private static RuntimeException createInvalidIdentifierException(Map<String, Object> xmlObject) {
+		return new RuntimeException("Invalid XML of Identifiable. No valid identification is present. " + xmlObject.toString());
+	}
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/LangStringsXMLConverter.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/LangStringsXMLConverter.java
index b666389..e302fcc 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/LangStringsXMLConverter.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/LangStringsXMLConverter.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.factory.xml.converters.qualifier;
 
 import java.util.List;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/ReferableXMLConverter.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/ReferableXMLConverter.java
index 6c62b13..e4922f2 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/ReferableXMLConverter.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/ReferableXMLConverter.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.factory.xml.converters.qualifier;
 
 import java.util.Map;
@@ -11,6 +20,8 @@
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 
+import com.google.common.base.Strings;
+
 /**
  * Handles the conversion between an IReferable object and the XML tags<br>
  * &lt;aas:idShort&gt;, &lt;aas:category&gt;, &lt;aas:parent&gt; and &lt;aas:description&gt; in both directions
@@ -26,26 +37,33 @@
 	public static final String DESCRIPTION = "aas:description";
 
 	/**
-	 * Populates a given IReferable object with the data form the given XML
+	 * Populates a given Referable object with the data form the given XML
 	 * 
 	 * @param xmlObject the XML map containing the tag relevant for IReferable
-	 * @param referable the IReferable object to be populated -treated as Map here-
+	 * @param referable the Referable object to be populated
 	 */
 	@SuppressWarnings("unchecked")
-	public static void populateReferable(Map<String, Object> xmlObject, Map<String, Object> referable) {
-		//The IReferable object has to be treated as Map here, as the Interface has no Setters
-
+	public static void populateReferable(Map<String, Object> xmlObject, Referable referable) {
 		String idShort = XMLHelper.getString(xmlObject.get(ID_SHORT));
 		String category = XMLHelper.getString(xmlObject.get(CATEGORY));
 		
 		LangStrings description = parseDescription(xmlObject);
 		
 		Reference parent = ReferenceXMLConverter.parseReference((Map<String, Object>) xmlObject.get(PARENT));
+		if (Strings.isNullOrEmpty(idShort)) {
+			throw new RuntimeException("Invalid XML of Referable. No valid idShort is present. " + xmlObject.toString());
+		}
+		referable.setIdShort(idShort);
 		
-		referable.put(Referable.IDSHORT, idShort);
-		referable.put(Referable.CATEGORY, category);
-		referable.put(Referable.DESCRIPTION, description);
-		referable.put(Referable.PARENT, parent);
+		if (!Strings.isNullOrEmpty(category)) {
+			referable.setCategory(category);
+		}
+		if (description != null) {
+			referable.setDescription(description);
+		}
+		if (parent != null) {
+			referable.setParent(parent);
+		}
 	}
 	
 
@@ -60,7 +78,7 @@
 		
 		Map<String, Object> descObj = (Map<String, Object>) xmlObject.get(DESCRIPTION);
 		if (descObj == null) {
-			return new LangStrings();
+			return null;
 		}
 		
 		return LangStringsXMLConverter.parseLangStrings(descObj);
@@ -91,7 +109,7 @@
 			root.appendChild(categoryElem);
 		}
 		
-		if(!referable.getDescription().isEmpty()) {
+		if(referable.getDescription() != null && !referable.getDescription().isEmpty()) {
 			Element descriptionRoot = document.createElement(DESCRIPTION);
 			LangStringsXMLConverter.buildLangStringsXML(document, descriptionRoot, referable.getDescription());
 			root.appendChild(descriptionRoot);
@@ -106,4 +124,4 @@
 		
 	}	
 
-}
\ No newline at end of file
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/haskind/HasKindXMLConverter.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/haskind/HasKindXMLConverter.java
index f76f6ae..09a3d1f 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/haskind/HasKindXMLConverter.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/haskind/HasKindXMLConverter.java
@@ -1,13 +1,25 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.factory.xml.converters.qualifier.haskind;
 
 import java.util.Map;
 
 import org.eclipse.basyx.submodel.factory.xml.XMLHelper;
 import org.eclipse.basyx.submodel.metamodel.api.qualifier.haskind.IHasKind;
+import org.eclipse.basyx.submodel.metamodel.api.qualifier.haskind.ModelingKind;
 import org.eclipse.basyx.submodel.metamodel.map.qualifier.haskind.HasKind;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 
+import com.google.common.base.Strings;
+
 /**
  * Handles the conversion between an IHasKind object and the XML tag &lt;aas:kind&gt; in both directions
  * 
@@ -20,16 +32,16 @@
 	
 	
 	/**
-	 * Populates a given IHasKind object with the data form the given XML
+	 * Populates a given HasKind object with the data form the given XML
 	 * 
 	 * @param xmlObject the XML map containing the &lt;aas:kind&gt; tag
-	 * @param hasKind the IHasKind object to be populated -treated as Map here-
+	 * @param hasKind the HasKind object to be populated
 	 */
-	public static void populateHasKind(Map<String, Object> xmlObject, Map<String, Object> hasKind) {
-		//The IHasKind object has to be treated as Map here, as the Interface has no Setters
-		
+	public static void populateHasKind(Map<String, Object> xmlObject, HasKind hasKind) {
 		String hasKindValue = XMLHelper.getString(xmlObject.get(KIND));
-		hasKind.put(HasKind.KIND, hasKindValue);
+		if (!Strings.isNullOrEmpty(hasKindValue)) {
+			hasKind.setModelingKind(ModelingKind.fromString(hasKindValue));	
+		}
 	}
 	
 	
@@ -48,4 +60,4 @@
 			root.appendChild(kindRoot);
 		}
 	}
-}
\ No newline at end of file
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/qualifiable/QualifiableXMLConverter.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/qualifiable/QualifiableXMLConverter.java
index dfd209c..c4ab1d6 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/qualifiable/QualifiableXMLConverter.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/qualifiable/QualifiableXMLConverter.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.factory.xml.converters.qualifier.qualifiable;
 
 import java.util.Collection;
@@ -13,10 +22,14 @@
 import org.eclipse.basyx.submodel.metamodel.api.qualifier.qualifiable.IQualifiable;
 import org.eclipse.basyx.submodel.metamodel.api.qualifier.qualifiable.IQualifier;
 import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasSemantics;
 import org.eclipse.basyx.submodel.metamodel.map.qualifier.qualifiable.Formula;
 import org.eclipse.basyx.submodel.metamodel.map.qualifier.qualifiable.Qualifiable;
 import org.eclipse.basyx.submodel.metamodel.map.qualifier.qualifiable.Qualifier;
 import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueTypeHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 
@@ -28,8 +41,9 @@
  */
 public class QualifiableXMLConverter {
 	
+	private static Logger logger = LoggerFactory.getLogger(QualifiableXMLConverter.class);
+
 	public static final String QUALIFIER = "aas:qualifier";
-	public static final String QUALIFIERS = "aas:qualifiers";
 	public static final String FORMULA = "aas:formula";
 	public static final String DEPENDS_ON_REFS = "aas:dependsOnRefs";
 	public static final String REFERENCE = "aas:reference";
@@ -40,17 +54,17 @@
 	
 
 	/**
-	 * Populates a given IQualifiable object with the data form the given XML
+	 * Populates a given Qualifiable object with the data form the given XML
 	 * 
 	 * @param xmlObject the XML map containing the &lt;aas:qualifier&gt; tag
-	 * @param qualifiable the IQualifiable object to be populated -treated as Map here-
+	 * @param qualifiable the Qualifiable object to be populated
 	 */
 	@SuppressWarnings("unchecked")
-	public static void populateQualifiable(Map<String, Object> xmlObject, Map<String, Object> qualifiable) {
-		//The IQualifiable object has to be treated as Map here, as the Interface has no Setters
-		
+	public static void populateQualifiable(Map<String, Object> xmlObject, Qualifiable qualifiable) {
 		Map<String, Object> qualifierObj = (Map<String, Object>) xmlObject.get(QUALIFIER);
-		qualifiable.put(Qualifiable.CONSTRAINTS, parseConstraints(qualifierObj));
+		if (qualifierObj != null) {
+			qualifiable.setQualifiers(parseConstraints(qualifierObj));
+		}
 	}
 	
 	
@@ -60,26 +74,18 @@
 	 * @param xmlConstraints the XML map containing the &lt;aas:formula&gt; and &lt;aas:qualifier&gt; tags
 	 * @return the Set of IConstraint objects parsed
 	 */
-	@SuppressWarnings("unchecked")
 	private static Collection<IConstraint> parseConstraints(Map<String, Object> xmlConstraints) {
 		Collection<IConstraint> constraints = new HashSet<>();
 		
 		if(xmlConstraints == null) return constraints;
 		
-		List<Map<String, Object>> xmlQualifiersList = XMLHelper.getList(xmlConstraints.get(QUALIFIERS));
-		
-		for (Map<String, Object> xmlQualifiers : xmlQualifiersList) {
+		List<Map<String, Object>> xmlQualifier = XMLHelper.getList(xmlConstraints.get(QUALIFIER));
+		xmlQualifier.stream().map(QualifiableXMLConverter::parseQualifier).forEach(constraints::add);
+
 			
-			Map<String, Object> xmlFormula = (Map<String, Object>) xmlQualifiers.get(FORMULA);
-			if(xmlFormula != null) {
-				constraints.add(parseFormula(xmlFormula));
-			}
+		List<Map<String, Object>> xmlFormula = XMLHelper.getList(xmlConstraints.get(FORMULA));
+		xmlFormula.stream().map(QualifiableXMLConverter::parseFormula).forEach(constraints::add);
 			
-			Map<String, Object> xmlQualifier = (Map<String, Object>) xmlQualifiers.get(QUALIFIER);
-			if(xmlQualifier != null) {
-				constraints.add(parseQualifier(xmlQualifier));
-			}
-		}
 		
 		return constraints;
 	}
@@ -121,13 +127,17 @@
 		Reference ref = ReferenceXMLConverter.parseReference(qualifierValueIdObj);
 		
 		Qualifier qualifier = new Qualifier();
-		HasSemanticsXMLConverter.populateHasSemantics(xmlQualifier, qualifier);
+		HasSemanticsXMLConverter.populateHasSemantics(xmlQualifier, HasSemantics.createAsFacade(qualifier));
 		
 		qualifier.setType(type);
 		qualifier.setValue(value);
 		qualifier.setValueId(ref);
-		qualifier.setValueType(valueType);
-		
+
+		if (valueType == null || valueType.isEmpty()) {
+			logger.warn("Creating element " + xmlQualifier + " without mandatory valueType!");
+		} else {
+			qualifier.setValueType(ValueTypeHelper.fromName(valueType));
+		}
 		return qualifier;
 	}
 
@@ -143,17 +153,17 @@
 	 * @param qualifiable the IQualifiable object to be converted to XML
 	 */
 	public static void populateQualifiableXML(Document document, Element root, IQualifiable qualifiable) {
-		if(qualifiable.getQualifier() == null || qualifiable.getQualifier().size() == 0) return;
+		if(qualifiable.getQualifiers() == null || qualifiable.getQualifiers().size() == 0) return;
 		
 		
-		Collection<IConstraint> constraints = qualifiable.getQualifier();
+		Collection<IConstraint> constraints = qualifiable.getQualifiers();
 		
 		Element qualifierRoot = document.createElement(QUALIFIER);
 		
 		for (IConstraint constraint : constraints) {
 			qualifierRoot.appendChild(buildQualifiersXML(document, constraint));
 		}
-		
+
 		root.appendChild(qualifierRoot);
 	}
 	
@@ -161,21 +171,22 @@
 	/**
 	 * Builds XML from a given IConstraint objcet
 	 * 
-	 * @param document the XML document
-	 * @param constraint the IConstraint to be converted to XML
-	 * @return the &lt;aas:qualifiers&gt; XML tag build from the IConstraint
+	 * @param document
+	 *            the XML document
+	 * @param constraint
+	 *            the IConstraint to be converted to XML
+	 * @return the &lt;aas:qualifier&gt; XML tag build from the IConstraint
 	 */
 	private static Element buildQualifiersXML(Document document, IConstraint constraint) {
-		Element qualifiersRoot = document.createElement(QUALIFIERS);
-		
+
 		//the constraints can be IFormula or IQualifier
 		if(constraint instanceof IFormula) {
-			qualifiersRoot.appendChild(buildFormulaXML(document, (IFormula) constraint));
+			return buildFormulaXML(document, (IFormula) constraint);
 		} else if(constraint instanceof IQualifier) {
-			qualifiersRoot.appendChild(buildQualifierXML(document, (IQualifier) constraint));
+			return buildQualifierXML(document, (IQualifier) constraint);
 		}
 		
-		return qualifiersRoot;
+		throw new RuntimeException("Unknown qualifier type " + constraint);
 	}
 	
 	
@@ -209,7 +220,7 @@
 		IReference qualId = qualifier.getValueId();
 		String type = XMLHelper.getString(qualifier.getType());
 		String value = XMLHelper.getString(qualifier.getValue());
-		String valueType = XMLHelper.getString(qualifier.getValueType());
+		String valueType = qualifier.getValueType().toString();
 		Element qualifierRoot = document.createElement(QUALIFIER);
 		
 		Element qualifierValueId = document.createElement(VALUE_ID);
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/reference/ReferenceXMLConverter.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/reference/ReferenceXMLConverter.java
index 1f19023..39afdad 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/reference/ReferenceXMLConverter.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/reference/ReferenceXMLConverter.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.factory.xml.converters.reference;
 
 import java.util.ArrayList;
@@ -181,4 +190,4 @@
 		
 		return xmlKey;
 	}
-}
\ No newline at end of file
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/SubmodelElementCollectionXMLConverter.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/SubmodelElementCollectionXMLConverter.java
index 38cfc77..8768403 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/SubmodelElementCollectionXMLConverter.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/SubmodelElementCollectionXMLConverter.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.factory.xml.converters.submodelelement;
 
 import java.util.Collection;
@@ -67,7 +76,7 @@
 		orderedElem.appendChild(document.createTextNode(isOrdered));
 		smElemCollectionRoot.appendChild(orderedElem);
 		
-		Collection<ISubmodelElement> elems = smElemCollection.getValue();
+		Collection<ISubmodelElement> elems = smElemCollection.getSubmodelElements().values();
 		
 		//recursively build the SubmodelElements contained in the ElementCollection
 		if(elems != null) {
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/SubmodelElementXMLConverter.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/SubmodelElementXMLConverter.java
index 46b88e1..6d0545d 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/SubmodelElementXMLConverter.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/SubmodelElementXMLConverter.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.factory.xml.converters.submodelelement;
 
 import java.util.ArrayList;
@@ -20,7 +29,9 @@
 import org.eclipse.basyx.submodel.factory.xml.converters.submodelelement.entity.EntityXMLConverter;
 import org.eclipse.basyx.submodel.factory.xml.converters.submodelelement.event.BasicEventXMLConverter;
 import org.eclipse.basyx.submodel.factory.xml.converters.submodelelement.operation.OperationXMLConverter;
+import org.eclipse.basyx.submodel.factory.xml.converters.submodelelement.relationship.AnnotatedRelationshipElementXMLConverter;
 import org.eclipse.basyx.submodel.factory.xml.converters.submodelelement.relationship.RelationshipElementXMLConverter;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
 import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
 import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElementCollection;
 import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IBlob;
@@ -32,25 +43,32 @@
 import org.eclipse.basyx.submodel.metamodel.api.submodelelement.entity.IEntity;
 import org.eclipse.basyx.submodel.metamodel.api.submodelelement.event.IBasicEvent;
 import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperation;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.relationship.IAnnotatedRelationshipElement;
 import org.eclipse.basyx.submodel.metamodel.api.submodelelement.relationship.IRelationshipElement;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasDataSpecification;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasSemantics;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.haskind.HasKind;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.qualifiable.Qualifiable;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElement;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.Blob;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.File;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.MultiLanguageProperty;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.Range;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.ReferenceElement;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.range.Range;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.entity.Entity;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.event.BasicEvent;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.relationship.AnnotatedRelationshipElement;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.relationship.RelationshipElement;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 
 /**
  * Parses &lt;aas:submodelElements&gt; and builds the SubmodelElement objects from it <br>
- * Builds &lt;aas:submodelElements&gt; form a given Collection of SubmodelElement
+ * Builds &lt;aas:submodelElements&gt; from a given Collection of SubmodelElement
  * 
  * @author conradi
  *
@@ -59,8 +77,10 @@
 	
 	public static final String SUBMODEL_ELEMENTS = "aas:submodelElements";
 	public static final String SUBMODEL_ELEMENT = "aas:submodelElement";
+	public static final String DATA_ELEMENT = "aas:dataElement";
 	public static final String VALUE = "aas:value";
 	public static final String VALUE_TYPE = "aas:valueType";
+	public static final String VALUE_ID = "aas:valueId";
 	public static final String MIME_TYPE = "aas:mimeType";
 
 	
@@ -68,7 +88,7 @@
 	 * Parses a given Map containing the XML tag &lt;aas:submodelElements&gt;
 	 * 
 	 * @param xmlSubmodelElements a Map of the XML tag &lt;aas:submodelElements&gt;
-	 * @return a List with the ISubmodelElement Objects parsed form the XML  
+	 * @return a List with the ISubmodelElement Objects parsed from the XML  
 	 */
 	@SuppressWarnings("unchecked")
 	public static List<ISubmodelElement> parseSubmodelElements(Map<String, Object> xmlSubmodelElements) {
@@ -78,10 +98,10 @@
 	
 
 	/**
-	 * Parses the individual &lt;aas:submodelElement&gt; tags form the Map
+	 * Parses the individual &lt;aas:submodelElement&gt; tags from the Map
 	 * 
 	 * @param xmlObject a Map of &lt;aas:submodelElement&gt; tags
-	 * @return a List with the ISubmodelElement Objects parsed form the XML 
+	 * @return a List with the ISubmodelElement Objects parsed from the XML 
 	 */
 	protected static List<ISubmodelElement> getSubmodelElements(Map<String, Object> xmlObject) {
 		List<ISubmodelElement> submodelElemList = new ArrayList<>();
@@ -100,14 +120,14 @@
 	 * Parses the one SubmodelElement
 	 * 
 	 * @param xmlObject a Map of the SubmodelElement XML
-	 * @return a List with the ISubmodelElement Objects parsed form the XML 
+	 * @return a List with the ISubmodelElement Objects parsed from the XML 
 	 */
 	@SuppressWarnings("unchecked")
-	protected static SubmodelElement getSubmodelElement(Map<String, Object> xmlObject) {
+	public static SubmodelElement getSubmodelElement(Map<String, Object> xmlObject) {
 		
 		if (xmlObject.containsKey(PropertyXMLConverter.PROPERTY)) {
 			xmlObject = (Map<String, Object>) xmlObject.get(PropertyXMLConverter.PROPERTY);
-			return PropertyXMLConverter.parsePropery(xmlObject);
+			return PropertyXMLConverter.parseProperty(xmlObject);
 		}
 		else if (xmlObject.containsKey(BasicEventXMLConverter.BASIC_EVENT)) {
 			xmlObject = (Map<String, Object>) xmlObject.get(BasicEventXMLConverter.BASIC_EVENT);
@@ -149,6 +169,11 @@
 					RelationshipElementXMLConverter.RELATIONSHIP_ELEMENT);
 			return RelationshipElementXMLConverter.parseRelationshipElement(xmlObject);
 		}
+		else if(xmlObject.containsKey(AnnotatedRelationshipElementXMLConverter.ANNOTATED_RELATIONSHIP_ELEMENT)) {
+			xmlObject = (Map<String, Object>) xmlObject.get(
+					AnnotatedRelationshipElementXMLConverter.ANNOTATED_RELATIONSHIP_ELEMENT);
+			return AnnotatedRelationshipElementXMLConverter.parseAnnotatedRelationshipElement(xmlObject);
+		}
 		else if(xmlObject.containsKey(OperationXMLConverter.OPERATION)) {
 			xmlObject = (Map<String, Object>) xmlObject.get(OperationXMLConverter.OPERATION);
 			return OperationXMLConverter.parseOperation(xmlObject);
@@ -166,11 +191,11 @@
 	 */
 	@SuppressWarnings("unchecked")
 	protected static void populateSubmodelElement(Map<String, Object> xmlObject, ISubmodelElement submodelElement) {
-		ReferableXMLConverter.populateReferable(xmlObject, (Map<String, Object>) submodelElement);
-		QualifiableXMLConverter.populateQualifiable(xmlObject, (Map<String, Object>) submodelElement);
-		HasDataSpecificationXMLConverter.populateHasDataSpecification(xmlObject, (Map<String, Object>) submodelElement);
-		HasSemanticsXMLConverter.populateHasSemantics(xmlObject, (Map<String, Object>) submodelElement);
-		HasKindXMLConverter.populateHasKind(xmlObject, (Map<String, Object>) submodelElement);
+		ReferableXMLConverter.populateReferable(xmlObject, Referable.createAsFacadeNonStrict((Map<String, Object>) submodelElement, KeyElements.SUBMODELELEMENT));
+		QualifiableXMLConverter.populateQualifiable(xmlObject, Qualifiable.createAsFacade((Map<String, Object>) submodelElement));
+		HasDataSpecificationXMLConverter.populateHasDataSpecification(xmlObject, HasDataSpecification.createAsFacade((Map<String, Object>) submodelElement));
+		HasSemanticsXMLConverter.populateHasSemantics(xmlObject, HasSemantics.createAsFacade((Map<String, Object>) submodelElement));
+		HasKindXMLConverter.populateHasKind(xmlObject, HasKind.createAsFacade((Map<String, Object>) submodelElement));
 	}
 	
 
@@ -180,7 +205,7 @@
 	 * Builds the SubmodelElemensts XML tag &lt;aas:submodelElements&gt;
 	 * 
 	 * @param document the XML document
-	 * @param submodelElements the SubmodelElements of the SubModel 
+	 * @param submodelElements the SubmodelElements of the Submodel 
 	 * @return XML Element with the root tag &lt;aas:submodelElements&gt;
 	 */
 	public static Element buildSubmodelElementsXML(Document document, Collection<ISubmodelElement> submodelElements) {
@@ -191,7 +216,7 @@
 	
 	
 	/**
-	 * Builds the individual SubmodelElement XML tags form a List of SubmodelElements and <br>
+	 * Builds the individual SubmodelElement XML tags from a List of SubmodelElements and <br>
 	 * populates the given root Element with them
 	 * 
 	 * @param document the XML document
@@ -215,7 +240,7 @@
 	 * @param submodelElement the SubmodelElement to build the XML for
 	 * @return the SubmodelElement XML tag
 	 */
-	protected static Element buildSubmodelElement(Document document, ISubmodelElement submodelElement) {
+	public static Element buildSubmodelElement(Document document, ISubmodelElement submodelElement) {
 		String type = submodelElement.getModelType();	
 		
 		switch (type) {
@@ -243,6 +268,9 @@
 			case RelationshipElement.MODELTYPE:
 				return RelationshipElementXMLConverter.buildRelationshipElement(
 						document, (IRelationshipElement) submodelElement);
+			case AnnotatedRelationshipElement.MODELTYPE:
+				return AnnotatedRelationshipElementXMLConverter.buildAnnotatedRelationshipElement(
+						document, (IAnnotatedRelationshipElement) submodelElement);
 			case Operation.MODELTYPE:
 				return OperationXMLConverter.buildOperation(document, (IOperation) submodelElement);
 			default:
@@ -265,4 +293,4 @@
 		QualifiableXMLConverter.populateQualifiableXML(document, root, submodelElement);
 		HasDataSpecificationXMLConverter.populateHasDataSpecificationXML(document, root, submodelElement);
 	}
-}
\ No newline at end of file
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/dataelement/BlobXMLConverter.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/dataelement/BlobXMLConverter.java
index c9e522f..64f7615 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/dataelement/BlobXMLConverter.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/dataelement/BlobXMLConverter.java
@@ -1,6 +1,14 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.factory.xml.converters.submodelelement.dataelement;
 
-import java.util.Base64;
 import java.util.Map;
 
 import org.eclipse.basyx.submodel.factory.xml.XMLHelper;
@@ -29,12 +37,11 @@
 	 * @return the parsed Blob
 	 */
 	public static Blob parseBlob(Map<String, Object> xmlObject) {
-		
 		String mimeType = XMLHelper.getString(xmlObject.get(MIME_TYPE));
 		String value = XMLHelper.getString(xmlObject.get(VALUE));
-		byte[] valueBytes = Base64.getDecoder().decode(value.getBytes());
-		
-		Blob blob = new Blob(valueBytes, mimeType);
+		Blob blob = new Blob();
+		blob.setMimeType(mimeType);
+		blob.setValue(value);
 		populateSubmodelElement(xmlObject, blob);
 		return blob;
 	}
@@ -54,7 +61,8 @@
 		
 		populateSubmodelElement(document, blobRoot, blob);
 		
-		String value = Base64.getEncoder().encodeToString(blob.getValue());
+		// Base64 encoded string
+		String value = blob.getValue();
 		String mimeType = blob.getMimeType();
 		
 		if(value != null) {
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/dataelement/FileXMLConverter.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/dataelement/FileXMLConverter.java
index d44f0f0..0301509 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/dataelement/FileXMLConverter.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/dataelement/FileXMLConverter.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.factory.xml.converters.submodelelement.dataelement;
 
 import java.util.Map;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/dataelement/MultiLanguagePropertyXMLConverter.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/dataelement/MultiLanguagePropertyXMLConverter.java
index 400ecc9..8b919c7 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/dataelement/MultiLanguagePropertyXMLConverter.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/dataelement/MultiLanguagePropertyXMLConverter.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.factory.xml.converters.submodelelement.dataelement;
 
 import java.util.Map;
@@ -15,7 +24,7 @@
 
 /**
  * Parses &lt;aas:multiLanguageProperty&gt; and builds the MultiLanguageProperty object from it <br>
- * Builds &lt;aas:multiLanguageProperty&gt; form a given MultiLanguageProperty object
+ * Builds &lt;aas:multiLanguageProperty&gt; from a given MultiLanguageProperty object
  * 
  * @author conradi
  *
@@ -23,7 +32,6 @@
 public class MultiLanguagePropertyXMLConverter extends SubmodelElementXMLConverter {
 	
 	public static final String MULTI_LANGUAGE_PROPERTY = "aas:multiLanguageProperty";
-	public static final String VALUE_ID = "aas:valueId";
 	
 	/**
 	 * Parses a Map containing the content of XML tag &lt;aas:multiLanguageProperty&gt;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/dataelement/PropertyXMLConverter.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/dataelement/PropertyXMLConverter.java
index 182f3b5..b402c72 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/dataelement/PropertyXMLConverter.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/dataelement/PropertyXMLConverter.java
@@ -1,12 +1,24 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.factory.xml.converters.submodelelement.dataelement;
 
 import java.util.Map;
 
 import org.eclipse.basyx.submodel.factory.xml.XMLHelper;
+import org.eclipse.basyx.submodel.factory.xml.converters.reference.ReferenceXMLConverter;
 import org.eclipse.basyx.submodel.factory.xml.converters.submodelelement.SubmodelElementXMLConverter;
+import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
 import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetypedef.PropertyValueTypeDefHelper;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueTypeHelper;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.w3c.dom.Document;
@@ -14,7 +26,7 @@
 
 /**
  * Parses &lt;aas:property&gt; and builds the Property object from it <br>
- * Builds &lt;aas:property&gt; form a given Property object
+ * Builds &lt;aas:property&gt; from a given Property object
  * 
  * @author conradi
  *
@@ -32,7 +44,8 @@
 	 * @param xmlObject the Map with the content of XML tag &lt;aas:property&gt;
 	 * @return the parsed Property
 	 */
-	public static Property parsePropery(Map<String, Object> xmlObject) {
+	@SuppressWarnings("unchecked")
+	public static Property parseProperty(Map<String, Object> xmlObject) {
 		
 		Property property = new Property();
 		
@@ -41,9 +54,15 @@
 		String valueType = XMLHelper.getString(xmlObject.get(SubmodelElementXMLConverter.VALUE_TYPE));
 		String value = XMLHelper.getString(xmlObject.get(SubmodelElementXMLConverter.VALUE));
 		
-		property.set(value, PropertyValueTypeDefHelper.fromName(valueType));
+		Map<String, Object> xmlValueId = (Map<String, Object>) xmlObject.get(VALUE_ID);
+		Reference valueId = ReferenceXMLConverter.parseReference(xmlValueId);
 		
-		//FIXME the XML-ELement valueId has no corresponding field in Property
+		property.set(value, ValueTypeHelper.fromName(valueType));
+		
+		if(valueId != null) {
+			property.setValueId(valueId);
+		}
+		
 		return property;
 	}
 	
@@ -62,12 +81,18 @@
 		
 		populateSubmodelElement(document, propertyRoot, prop);
 
-		//FIXME the XML-ELement valueId has no corresponding field in Property
 		String value = null;
 		
+		IReference valueId = prop.getValueId();
+		if(valueId != null) {
+			Element valueIdRoot = document.createElement(VALUE_ID);
+			valueIdRoot.appendChild(ReferenceXMLConverter.buildReferenceXML(document, valueId)); 
+			propertyRoot.appendChild(valueIdRoot);
+		}	
+		
 		//for some reason, get() in ISingleProperty might throw an Exception
 		try {
-			Object valueObj = prop.get();
+			Object valueObj = prop.getValue();
 			value = valueObj == null ? null : valueObj.toString();
 		} catch (Exception e) {
 			logger.error("Exeption in buildProperty!", e);
@@ -79,7 +104,7 @@
 			propertyRoot.appendChild(valueEle);
 		}
 		
-		String valueType = prop.getValueType();
+		String valueType = prop.getValueType().toString();
 		if (valueType != null) {
 			Element valueTypeElem = document.createElement(SubmodelElementXMLConverter.VALUE_TYPE);
 			valueTypeElem.appendChild(document.createTextNode(valueType));
@@ -88,4 +113,4 @@
 		
 		return propertyRoot;
 	}
-}
\ No newline at end of file
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/dataelement/RangeXMLConverter.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/dataelement/RangeXMLConverter.java
index 833b012..58fdb7c 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/dataelement/RangeXMLConverter.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/dataelement/RangeXMLConverter.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.factory.xml.converters.submodelelement.dataelement;
 
 import java.util.Map;
@@ -5,7 +14,8 @@
 import org.eclipse.basyx.submodel.factory.xml.XMLHelper;
 import org.eclipse.basyx.submodel.factory.xml.converters.submodelelement.SubmodelElementXMLConverter;
 import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IRange;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.Range;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueTypeHelper;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.range.Range;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 
@@ -33,7 +43,7 @@
 		String valueType = XMLHelper.getString(xmlObject.get(VALUE_TYPE));
 		String min = XMLHelper.getString(xmlObject.get(MIN));
 		String max = XMLHelper.getString(xmlObject.get(MAX));
-		Range range = new Range(valueType, min, max);
+		Range range = new Range(ValueTypeHelper.fromName(valueType), min, max);
 		populateSubmodelElement(xmlObject, range);
 		return range;
 	}
@@ -68,7 +78,7 @@
 			rangeRoot.appendChild(minRoot);
 		}
 		
-		String valueType = range.getValueType();
+		String valueType = range.getValueType().toString();
 		if(valueType != null) {
 			Element valueTypeRoot = document.createElement(VALUE_TYPE);
 			valueTypeRoot.appendChild(document.createTextNode(valueType));
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/dataelement/ReferenceElementXMLConverter.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/dataelement/ReferenceElementXMLConverter.java
index b5ab11e..f51283f 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/dataelement/ReferenceElementXMLConverter.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/dataelement/ReferenceElementXMLConverter.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.factory.xml.converters.submodelelement.dataelement;
 
 import java.util.Map;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/entity/EntityXMLConverter.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/entity/EntityXMLConverter.java
index c705416..60a81ef 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/entity/EntityXMLConverter.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/entity/EntityXMLConverter.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.factory.xml.converters.submodelelement.entity;
 
 import java.util.Collection;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/event/BasicEventXMLConverter.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/event/BasicEventXMLConverter.java
index 784e9ed..c8b3051 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/event/BasicEventXMLConverter.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/event/BasicEventXMLConverter.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.factory.xml.converters.submodelelement.event;
 
 import java.util.Map;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/operation/OperationXMLConverter.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/operation/OperationXMLConverter.java
index 773e851..890f941 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/operation/OperationXMLConverter.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/operation/OperationXMLConverter.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.factory.xml.converters.submodelelement.operation;
 
 import java.util.ArrayList;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/relationship/AnnotatedRelationshipElementXMLConverter.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/relationship/AnnotatedRelationshipElementXMLConverter.java
new file mode 100644
index 0000000..2843268
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/relationship/AnnotatedRelationshipElementXMLConverter.java
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.factory.xml.converters.submodelelement.relationship;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.basyx.submodel.factory.xml.XMLHelper;
+import org.eclipse.basyx.submodel.factory.xml.converters.submodelelement.SubmodelElementCollectionXMLConverter;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IDataElement;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.relationship.IAnnotatedRelationshipElement;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.relationship.AnnotatedRelationshipElement;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * Parses &lt;aas:annotatedRelationshipElement&gt; and builds an AnnotatedRelationshipElement object from it <br>
+ * Builds &lt;aas:annotatedRelationshipElement&gt; from a given AnnotatedRelationshipElement
+ * 
+ * @author conradi
+ *
+ */
+public class AnnotatedRelationshipElementXMLConverter {
+	public static final String ANNOTATED_RELATIONSHIP_ELEMENT = "aas:annotatedRelationshipElement";
+	public static final String ANNOTATIONS = "aas:annotations";
+
+	/**
+	 * Builds a AnnotatedRelationshipElement object from the given XML
+	 * 
+	 * @param xmlObject the Map with the content of XML tag &lt;aas:annotatedRelationshipElement&gt;
+	 * @return the parsed AnnotatedRelationshipElement
+	 */
+	@SuppressWarnings("unchecked")
+	public static AnnotatedRelationshipElement parseAnnotatedRelationshipElement(Map<String, Object> xmlObject) {
+		AnnotatedRelationshipElement annotatedElement = new AnnotatedRelationshipElement();
+		
+		RelationshipElementXMLConverter.populateRelationshipElement(xmlObject, annotatedElement);
+		
+		Map<String, Object> xmlAnnotations = (Map<String, Object>) xmlObject.get(ANNOTATIONS);
+		List<Map<String, Object>> xmlDataElements = XMLHelper.getList(xmlAnnotations.get(SubmodelElementCollectionXMLConverter.DATA_ELEMENT));
+		
+		
+		List<IDataElement> dataElements = new ArrayList<>();
+		for(Map<String, Object> element: xmlDataElements) {
+			ISubmodelElement smElement = SubmodelElementCollectionXMLConverter.getSubmodelElement(element);
+			
+			// Check if all Elements contained in <aas:annotations> is an IDataElement
+			if(smElement instanceof IDataElement) {
+				dataElements.add((IDataElement) smElement);
+			} else {
+				throw new RuntimeException("AnnotatedRelationshipElement '" + annotatedElement.getIdShort() + "' can only contain IDataElement as annotation");
+			}
+		}
+		
+		annotatedElement.setAnnotation(dataElements);
+		return annotatedElement;
+	}
+	
+	
+	
+	
+	/**
+	 * Builds the &lt;aas:annotatedRelationshipElement&gt; XML tag for a AnnotatedRelationshipElement
+	 * 
+	 * @param document the XML document
+	 * @param relElem the IAnnotatedRelationshipElement to build the XML for
+	 * @return the &lt;aas:annotatedRelationshipElement&gt; XML tag for the given AnnotatedRelationshipElement
+	 */
+	public static Element buildAnnotatedRelationshipElement(Document document, IAnnotatedRelationshipElement annotatedElement) {
+		Element root = document.createElement(ANNOTATED_RELATIONSHIP_ELEMENT);
+		RelationshipElementXMLConverter.populateRelationshipElement(document, root, annotatedElement);
+		
+		Element annotationsRoot = document.createElement(ANNOTATIONS);
+		root.appendChild(annotationsRoot);
+		
+		for(IDataElement dataElement: annotatedElement.getValue().getAnnotations()) {
+			Element dataElementRoot = document.createElement(SubmodelElementCollectionXMLConverter.DATA_ELEMENT);
+			Element dataElementContent = SubmodelElementCollectionXMLConverter.buildSubmodelElement(document, dataElement);
+			dataElementRoot.appendChild(dataElementContent);
+			annotationsRoot.appendChild(dataElementRoot);
+		}
+		
+		return root;
+	}
+
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/relationship/RelationshipElementXMLConverter.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/relationship/RelationshipElementXMLConverter.java
index 892771d..c75c7f2 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/relationship/RelationshipElementXMLConverter.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/relationship/RelationshipElementXMLConverter.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.factory.xml.converters.submodelelement.relationship;
 
 import java.util.Map;
@@ -8,6 +17,7 @@
 import org.eclipse.basyx.submodel.metamodel.api.submodelelement.relationship.IRelationshipElement;
 import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.relationship.RelationshipElement;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.relationship.RelationshipElementValue;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 
@@ -26,27 +36,38 @@
 	
 	
 	/**
-	 * Parses a Map containing the content of XML tag &lt;aas:relationshipElement&gt;
+	 * Builds a RelationshipElement object from the given XML
 	 * 
 	 * @param xmlObject the Map with the content of XML tag &lt;aas:relationshipElement&gt;
 	 * @return the parsed RelationshipElement
 	 */
-	@SuppressWarnings("unchecked")
 	public static RelationshipElement parseRelationshipElement(Map<String, Object> xmlObject) {
+		RelationshipElement relElement = new RelationshipElement();
+		populateRelationshipElement(xmlObject, relElement);
+		return relElement;
+	}
+	
+	/**
+	 * Parses a Map containing the content of XML tag &lt;aas:relationshipElement&gt;
+	 * and populates a given RelationshipElement object
+	 * 
+	 * @param xmlObject the Map with the content of XML tag &lt;aas:relationshipElement&gt;
+	 * @param relElement the RelationshipElement to be populated
+	 */
+	@SuppressWarnings("unchecked")
+	public static void populateRelationshipElement(Map<String, Object> xmlObject, IRelationshipElement relElement) {
 		Map<String, Object> firstMap = (Map<String, Object>) xmlObject.get(FIRST);
 		Reference first = ReferenceXMLConverter.parseReference(firstMap);
 		
 		Map<String, Object> secondMap = (Map<String, Object>) xmlObject.get(SECOND);
 		Reference second = ReferenceXMLConverter.parseReference(secondMap);
 		
-		RelationshipElement relElement = new RelationshipElement(first, second);
+		relElement.setValue(new RelationshipElementValue(first, second));
+		
 		populateSubmodelElement(xmlObject, relElement);
-		return relElement;
 	}
 	
 	
-	
-	
 	/**
 	 * Builds the &lt;aas:relationshipElement&gt; XML tag for a RelationshipElement
 	 * 
@@ -56,22 +77,34 @@
 	 */
 	public static Element buildRelationshipElement(Document document, IRelationshipElement relElem) {
 		Element relElemRoot = document.createElement(RELATIONSHIP_ELEMENT);
+		populateRelationshipElement(document, relElemRoot, relElem);
+		return relElemRoot;
+	}
+	
+	/**
+	 * Builds the content for a given &lt;aas:relationshipElement&gt; XML tag
+	 * 
+	 * @param document the XML document
+	 * @param root the root Element of the new RelationshipElement
+	 * @param relElem the RelationShipElement
+	 */
+	public static void populateRelationshipElement(Document document, Element root, IRelationshipElement relElem) {
+		populateSubmodelElement(document, root, relElem);
 		
-		populateSubmodelElement(document, relElemRoot, relElem);
-
-		IReference first = relElem.getFirst();
+		RelationshipElementValue value = relElem.getValue();
+		
+		IReference first = value.getFirst();
 		if(first != null) {
 			Element derivedFromRoot = document.createElement(FIRST);
 			derivedFromRoot.appendChild(ReferenceXMLConverter.buildReferenceXML(document, first)); 
-			relElemRoot.appendChild(derivedFromRoot);
+			root.appendChild(derivedFromRoot);
 		}		
-		IReference second = relElem.getSecond();
+		IReference second = value.getSecond();
 		if(second != null) {
 			Element derivedFromRoot = document.createElement(SECOND);
 			derivedFromRoot.appendChild(ReferenceXMLConverter.buildReferenceXML(document, second)); 
-			relElemRoot.appendChild(derivedFromRoot);
+			root.appendChild(derivedFromRoot);
 		}
 		
-		return relElemRoot;
 	}
 }
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/IElement.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/IElement.java
index baccd95..bcb7d10 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/IElement.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/IElement.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.api;
 
 
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/IElementContainer.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/IElementContainer.java
index 093e1b2..cb27a8a 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/IElementContainer.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/IElementContainer.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.api;
 
 import java.util.Map;
@@ -18,7 +27,7 @@
 	 * 
 	 * @param element
 	 */
-	public void addSubModelElement(ISubmodelElement element);
+	public void addSubmodelElement(ISubmodelElement element);
 
 	/**
 	 * Gets all contained submodel elements
@@ -41,4 +50,16 @@
 	 */
 	public Map<String, IOperation> getOperations();
 	
+	/**
+	 * Gets a submodel element by name
+	 * @param id
+	 * @return submodel element
+	 */
+	ISubmodelElement getSubmodelElement(String id);
+	
+	/**
+	 * Deletes a submodel element by name
+	 * @param id
+	 */
+	void deleteSubmodelElement(String id);
 }
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/ISubModel.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/ISubModel.java
deleted file mode 100644
index 2f716ab..0000000
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/ISubModel.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package org.eclipse.basyx.submodel.metamodel.api;
-
-import org.eclipse.basyx.submodel.metamodel.api.qualifier.IHasDataSpecification;
-import org.eclipse.basyx.submodel.metamodel.api.qualifier.IHasSemantics;
-import org.eclipse.basyx.submodel.metamodel.api.qualifier.IIdentifiable;
-import org.eclipse.basyx.submodel.metamodel.api.qualifier.haskind.IHasKind;
-import org.eclipse.basyx.submodel.metamodel.api.qualifier.qualifiable.IQualifiable;
-
-/**
- * A submodel defines a specific aspect of the asset represented by the
- * AAS.<br/>
- * <br />
- * A submodel is used to structure the digital representation and technical
- * functionality of an Administration Shell into distinguishable parts. Each
- * submodel refers to a well-defined domain or subject matter. Submodels can
- * become standardized and thus become submodels types. Submodels can have
- * different life-cycles.
- * 
- * @author kuhn, schnicke
- *
- */
-public interface ISubModel extends IElement, IHasSemantics, IIdentifiable, IQualifiable, IHasDataSpecification, IHasKind, IElementContainer {
-}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/ISubmodel.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/ISubmodel.java
new file mode 100644
index 0000000..e034690
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/ISubmodel.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.metamodel.api;
+
+import java.util.Map;
+
+import org.eclipse.basyx.submodel.metamodel.api.qualifier.IHasDataSpecification;
+import org.eclipse.basyx.submodel.metamodel.api.qualifier.IHasSemantics;
+import org.eclipse.basyx.submodel.metamodel.api.qualifier.IIdentifiable;
+import org.eclipse.basyx.submodel.metamodel.api.qualifier.haskind.IHasKind;
+import org.eclipse.basyx.submodel.metamodel.api.qualifier.qualifiable.IQualifiable;
+
+/**
+ * A submodel defines a specific aspect of the asset represented by the
+ * AAS.<br/>
+ * <br />
+ * A submodel is used to structure the digital representation and technical
+ * functionality of an Administration Shell into distinguishable parts. Each
+ * submodel refers to a well-defined domain or subject matter. Submodels can
+ * become standardized and thus become submodels types. Submodels can have
+ * different life-cycles.
+ * 
+ * @author kuhn, schnicke
+ *
+ */
+public interface ISubmodel extends IElement, IHasSemantics, IIdentifiable, IQualifiable, IHasDataSpecification, IHasKind, IElementContainer {
+	
+	/**
+	 * Gets a Map<IdShort, smElement.getValue()> containing the values of all submodelElements
+	 * 
+	 * @return a Map with the values of all submodelElements
+	 */
+	public Map<String, Object> getValues();
+	
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/IDataSpecification.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/IDataSpecification.java
index 58e2cca..bf44669 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/IDataSpecification.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/IDataSpecification.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.api.dataspecification;
 
 import org.eclipse.basyx.submodel.metamodel.api.qualifier.IIdentifiable;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/IDataSpecificationContent.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/IDataSpecificationContent.java
index 6521605..8b9d837 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/IDataSpecificationContent.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/IDataSpecificationContent.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.api.dataspecification;
 
 /**
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/IDataSpecificationIEC61360Content.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/IDataSpecificationIEC61360Content.java
index 99cb931..955a51c 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/IDataSpecificationIEC61360Content.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/IDataSpecificationIEC61360Content.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.api.dataspecification;
 
 import java.util.Collection;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/IEmbeddedDataSpecification.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/IEmbeddedDataSpecification.java
index 212bbbb..b86fcf9 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/IEmbeddedDataSpecification.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/IEmbeddedDataSpecification.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.api.dataspecification;
 
 import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/IValueReferencePair.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/IValueReferencePair.java
index ba8f45a..e9603f5 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/IValueReferencePair.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/IValueReferencePair.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.api.dataspecification;
 
 import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/enums/DataTypeIEC61360.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/enums/DataTypeIEC61360.java
index e8bc45f..7dc731c 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/enums/DataTypeIEC61360.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/enums/DataTypeIEC61360.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.api.dataspecification.enums;
 
 import org.eclipse.basyx.submodel.metamodel.enumhelper.StandardizedLiteralEnum;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/enums/LevelType.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/enums/LevelType.java
index a5e6c87..436b2b4 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/enums/LevelType.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/enums/LevelType.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.api.dataspecification.enums;
 
 import org.eclipse.basyx.submodel.metamodel.enumhelper.StandardizedLiteralEnum;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/identifier/IIdentifier.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/identifier/IIdentifier.java
index 279ed92..4fb6faa 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/identifier/IIdentifier.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/identifier/IIdentifier.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.api.identifier;
 
 /**
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/identifier/IdentifierType.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/identifier/IdentifierType.java
index 58e232b..4082a5d 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/identifier/IdentifierType.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/identifier/IdentifierType.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.api.identifier;
 
 import org.eclipse.basyx.submodel.metamodel.enumhelper.StandardizedLiteralEnum;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/parts/IConceptDescription.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/parts/IConceptDescription.java
index cae6f17..ab2e2f8 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/parts/IConceptDescription.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/parts/IConceptDescription.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.api.parts;
 
 import java.util.Collection;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/IAdministrativeInformation.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/IAdministrativeInformation.java
index d30e318..0809b44 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/IAdministrativeInformation.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/IAdministrativeInformation.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.api.qualifier;
 
 
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/IHasDataSpecification.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/IHasDataSpecification.java
index 712e3c6..9914831 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/IHasDataSpecification.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/IHasDataSpecification.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.api.qualifier;
 
 import java.util.Collection;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/IHasSemantics.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/IHasSemantics.java
index a206a63..daed9c1 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/IHasSemantics.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/IHasSemantics.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.api.qualifier;
 
 import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/IIdentifiable.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/IIdentifiable.java
index b3bbe10..617425e 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/IIdentifiable.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/IIdentifiable.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.api.qualifier;
 
 import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/IReferable.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/IReferable.java
index e66b823..1c58991 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/IReferable.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/IReferable.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.api.qualifier;
 
 import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/IdShortValidator.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/IdShortValidator.java
new file mode 100644
index 0000000..79c96e9
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/IdShortValidator.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.metamodel.api.qualifier;
+
+/**
+ * Tests the validity of IdShorts according to DotAAS
+ * 
+ * @author schnicke
+ *
+ */
+public class IdShortValidator {
+	/*
+	 * Taken from DotAAS p. 50: "Constraint AASd-002: idShort shall only feature
+	 * letters, digits, underscore ("_"); starting mandatory with a letter."
+	 */
+	public static final String IDSHORT_REGEX = "[a-zA-Z][a-zA-Z0-9_]+";
+
+	/**
+	 * Returns true iff the idShort is valid according to DotAAS
+	 * 
+	 * @param idShort
+	 *            to test
+	 * @return test result
+	 */
+	public static boolean isValid(String idShort) {
+		if (idShort == null) {
+			return false;
+		}
+
+		return idShort.matches(IDSHORT_REGEX);
+	}
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/haskind/IHasKind.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/haskind/IHasKind.java
index ebf6bbc..2581347 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/haskind/IHasKind.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/haskind/IHasKind.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.api.qualifier.haskind;
 
 /**
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/haskind/ModelingKind.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/haskind/ModelingKind.java
index fff732b..b88a692 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/haskind/ModelingKind.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/haskind/ModelingKind.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.api.qualifier.haskind;
 
 import org.eclipse.basyx.submodel.metamodel.enumhelper.StandardizedLiteralEnum;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/qualifiable/IConstraint.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/qualifiable/IConstraint.java
index 736af18..b7050ad 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/qualifiable/IConstraint.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/qualifiable/IConstraint.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.api.qualifier.qualifiable;
 /**
  * Interface for Constraint
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/qualifiable/IFormula.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/qualifiable/IFormula.java
index 30be093..0cc79da 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/qualifiable/IFormula.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/qualifiable/IFormula.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.api.qualifier.qualifiable;
 
 import java.util.Collection;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/qualifiable/IQualifiable.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/qualifiable/IQualifiable.java
index 28b33f7..a27ee2f 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/qualifiable/IQualifiable.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/qualifiable/IQualifiable.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.api.qualifier.qualifiable;
 
 import java.util.Collection;
@@ -9,5 +18,5 @@
 */
 
 public interface IQualifiable {
-	public Collection<IConstraint> getQualifier();
+	public Collection<IConstraint> getQualifiers();
 }
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/qualifiable/IQualifier.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/qualifiable/IQualifier.java
index cfda524..c7c1e81 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/qualifiable/IQualifier.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/qualifiable/IQualifier.java
@@ -1,7 +1,17 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.api.qualifier.qualifiable;
 
 import org.eclipse.basyx.submodel.metamodel.api.qualifier.IHasSemantics;
 import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
 
 /**
  * Interface for Qualifier
@@ -13,9 +23,9 @@
 public interface IQualifier extends IHasSemantics, IConstraint {
 	public String getType();
 
-	public String getValue();
+	public Object getValue();
 
 	public IReference getValueId();
 	
-	public String getValueType();
+	public ValueType  getValueType();
 }
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/reference/IKey.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/reference/IKey.java
index 449045f..33eec09 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/reference/IKey.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/reference/IKey.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.api.reference;
 
 import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/reference/IReference.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/reference/IReference.java
index 6b97698..936250e 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/reference/IReference.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/reference/IReference.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.api.reference;
 
 import java.util.List;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/reference/enums/KeyElements.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/reference/enums/KeyElements.java
index be8b979..15b5401 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/reference/enums/KeyElements.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/reference/enums/KeyElements.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.api.reference.enums;
 
 import org.eclipse.basyx.submodel.metamodel.enumhelper.StandardizedLiteralEnum;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/reference/enums/KeyType.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/reference/enums/KeyType.java
index 74408b3..9e969a5 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/reference/enums/KeyType.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/reference/enums/KeyType.java
@@ -1,5 +1,15 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.api.reference.enums;
 
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
 import org.eclipse.basyx.submodel.metamodel.enumhelper.StandardizedLiteralEnum;
 import org.eclipse.basyx.submodel.metamodel.enumhelper.StandardizedLiteralEnumHelper;
 
@@ -16,7 +26,7 @@
 	/**
 	 * Enum values of IdentifierType
 	 */
-	CUSTOM("Custom"), IRDI("IRDI"), IRI("IRI"),
+	CUSTOM(IdentifierType.CUSTOM.toString()), IRDI(IdentifierType.IRDI.toString()), IRI(IdentifierType.IRI.toString()),
 
 	/**
 	 * Enum values of LocalKeyType
@@ -39,6 +49,10 @@
 		return standardizedLiteral;
 	}
 
+	public static KeyType fromIdentifierType(IdentifierType type) {
+		return fromString(type.toString());
+	}
+
 	public static KeyType fromString(String str) {
 		return StandardizedLiteralEnumHelper.fromLiteral(KeyType.class, str);
 	}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/ICapability.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/ICapability.java
index 911be7c..ccac1ac 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/ICapability.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/ICapability.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.api.submodelelement;
 
 /**
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/ISubmodelElement.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/ISubmodelElement.java
index 61eadb5..2fde991 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/ISubmodelElement.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/ISubmodelElement.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.api.submodelelement;
 
 import org.eclipse.basyx.submodel.metamodel.api.IElement;
@@ -6,6 +15,7 @@
 import org.eclipse.basyx.submodel.metamodel.api.qualifier.IReferable;
 import org.eclipse.basyx.submodel.metamodel.api.qualifier.haskind.IHasKind;
 import org.eclipse.basyx.submodel.metamodel.api.qualifier.qualifiable.IQualifiable;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElement;
 
 /**
  * A submodel element is an element suitable for the description and
@@ -16,4 +26,10 @@
  */
 public interface ISubmodelElement extends IElement, IHasDataSpecification, IReferable, IQualifiable, IHasSemantics, IHasKind {
 	public String getModelType();
+	
+	public Object getValue();
+	
+	public void setValue(Object value);
+
+	public SubmodelElement getLocalCopy();
 }
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/ISubmodelElementCollection.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/ISubmodelElementCollection.java
index 547978e..321afdf 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/ISubmodelElementCollection.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/ISubmodelElementCollection.java
@@ -1,8 +1,17 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.api.submodelelement;
 
-import java.util.Collection;
 import java.util.Map;
 
+import org.eclipse.basyx.submodel.metamodel.api.IElementContainer;
 import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
 import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperation;
 
@@ -12,9 +21,7 @@
  * @author rajashek, schnicke
  *
  */
-public interface ISubmodelElementCollection extends ISubmodelElement {
-	
-	public Collection<ISubmodelElement> getValue();
+public interface ISubmodelElementCollection extends ISubmodelElement, IElementContainer {
 	
 	/**
 	 * Gets if the collection is ordered or unordered
@@ -35,6 +42,7 @@
 	 * 
 	 * @return
 	 */
+	@Override
 	public Map<String, ISubmodelElement> getSubmodelElements();
 
 	/**
@@ -42,6 +50,7 @@
 	 * 
 	 * @return
 	 */
+	@Override
 	public Map<String, IProperty> getProperties();
 
 	/**
@@ -49,5 +58,6 @@
 	 * 
 	 * @return
 	 */
+	@Override
 	public Map<String, IOperation> getOperations();
-}
\ No newline at end of file
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/SubmodelElementIdShortBlacklist.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/SubmodelElementIdShortBlacklist.java
new file mode 100644
index 0000000..d7c3617
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/SubmodelElementIdShortBlacklist.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.metamodel.api.submodelelement;
+
+import java.util.Arrays;
+
+/**
+ * Tests if an IdShort of a SubmodelElement is blacklisted due to API
+ * constraints
+ * 
+ * @author schnicke
+ *
+ */
+public class SubmodelElementIdShortBlacklist {
+	/*
+	 * Due to API definition for SubmodelElementCollections
+	 * (/submodelElements/$IdShort1/.../$IdShortN) it is not possible to distinguish
+	 * if a SubmodelElement with idShort "value" or "invocationList" was requested
+	 * or the endpoint defined in the API. Thus, these keywords are forbidden as
+	 * idShort
+	 * 
+	 * E.g. /submodelElements/smCollectionId/value --> Is value here the /value
+	 * endpoint or a SubmodelElement with idShort value?
+	 */
+	public static final String[] BLACKLIST = { "value", "invocationList" };
+
+	/**
+	 * Returns true iff an idShort is blacklisted
+	 * 
+	 * @param idShort
+	 *            to test
+	 * @return test result
+	 */
+	public static boolean isBlacklisted(String idShort) {
+		return Arrays.asList(BLACKLIST).contains(idShort);
+	}
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IBlob.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IBlob.java
index 4e972e2..051676c 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IBlob.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IBlob.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement;
 
 /**
@@ -9,13 +18,50 @@
  */
 public interface IBlob extends IDataElement {
 	/**
-	 * Gets the value of the BLOB instance of a blob data element.
+	 * Gets the value of the Blob instance of a blob data element.
+	 * The returned value is Base64 encoded.
 	 * 
 	 * @return
 	 */
-	public byte[] getValue();
+	@Override
+	public String getValue();
 	
 	/**
+	 * Sets a Base64 encoded value of the BLOB instance of a blob data element.
+	 * 
+	 * @param bytes
+	 */
+	public void setValue(String value);
+
+	/**
+	 * Gets the value of the Blob instance of a blob data element.
+	 * 
+	 * @return
+	 */
+	public byte[] getByteArrayValue();
+
+	/**
+	 * Sets the value of the Blob instance of a blob data element.
+	 * 
+	 * @param bytes
+	 */
+	public void setByteArrayValue(byte[] value);
+
+	/**
+	 * Returns the UTF8 String representation of the byte array BLOB value
+	 *
+	 * @return
+	 */
+	public String getUTF8String();
+
+	/**
+	 * Sets an UTF8 string as an encoded byte array in the BLOB data element value
+	 * 
+	 * @param text
+	 */
+	public void setUTF8String(String text);
+
+	/**
 	 * Gets the mime type of the content of the BLOB. The mime type states which
 	 * file extension the file has. <br />
 	 * Valid values are e.g. “application/json”, “application/xls”, ”image/jpg”.
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IDataElement.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IDataElement.java
index 1210776..1b21612 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IDataElement.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IDataElement.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement;
 
 import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IFile.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IFile.java
index c3f8686..4c86bcb 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IFile.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IFile.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement;
 
 /**
@@ -14,9 +23,18 @@
 	 * 
 	 * @return
 	 */
+	@Override
 	public String getValue();
 	
 	/**
+	 * Sets path and name of the referenced file (with file extension). The path can
+	 * be absolute or relative.
+	 * 
+	 * @param value
+	 */
+	public void setValue(String value);
+
+	/**
 	 * Gets mime type of the content of the file.
 	 * 
 	 * @return
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IMultiLanguageProperty.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IMultiLanguageProperty.java
index d05f307..af10ec8 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IMultiLanguageProperty.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IMultiLanguageProperty.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement;
 
 import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
@@ -12,13 +21,21 @@
 public interface IMultiLanguageProperty extends IDataElement {
 
 	/**
-	 * Gets the value of the property instance
+	 * Gets the {@link LangStrings} value of the property instance
 	 * 
 	 * @return
 	 */
+	@Override
 	LangStrings getValue();
 
 	/**
+	 * Sets the {@link LangStrings} value of the property instance
+	 * 
+	 * @param value
+	 */
+	void setValue(LangStrings value);
+
+	/**
 	 * Gets the reference to the global unique id of a coded value.
 	 * 
 	 * @return
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IProperty.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IProperty.java
index 20d1381..9f5c486 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IProperty.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IProperty.java
@@ -1,8 +1,17 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement;
 
 import org.eclipse.basyx.submodel.metamodel.api.IElement;
 import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
-import org.eclipse.basyx.vab.exception.provider.ProviderException;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
 
 /**
  * Interface for IElement properties
@@ -12,26 +21,11 @@
  */
 public interface IProperty extends IElement, IDataElement {
 	/**
-	 * Get property value
-	 * 
-	 * @return Property value
-	 * @throws Exception
-	 */
-	public Object get() throws Exception;
-
-	/**
-	 * Set property value
-	 * 
-	 * @throws ProviderException
-	 */
-	public void set(Object newValue) throws ProviderException;
-
-	/**
 	 * Gets the data type of the value
 	 * 
 	 * @return
 	 */
-	public String getValueType();
+	public ValueType getValueType();
 
 	/**
 	 * Gets the reference to the global unique id of a coded value.
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IRange.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IRange.java
index db8a6f2..c7d5bdb 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IRange.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IRange.java
@@ -1,5 +1,17 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement;
 
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.range.RangeValue;
+
 /**
  * A range data element is a data element that defines a range with min and max.
  * 
@@ -12,7 +24,7 @@
 	 * 
 	 * @return
 	 */
-	String getValueType();
+	ValueType getValueType();
 
 	/**
 	 * Returns the minimum value of the range. <br />
@@ -31,4 +43,15 @@
 	 * infinite.
 	 */
 	Object getMax();
+
+	@Override
+	RangeValue getValue();
+
+	/**
+	 * Sets the value of the range represented by the Range submodel element
+	 * 
+	 * @param value
+	 *            the range
+	 */
+	void setValue(RangeValue value);
 }
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IReferenceElement.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IReferenceElement.java
index 92b016b..7634155 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IReferenceElement.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IReferenceElement.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement;
 
 import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
@@ -18,6 +27,15 @@
 	 * 
 	 * @return
 	 */
+	@Override
 	public IReference getValue();
 
+	/**
+	 * Sets the reference to any other referable element of the same or of any other
+	 * AAS or a reference to an external object or entity
+	 * 
+	 * @param value
+	 */
+	public void setValue(IReference value);
+
 }
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/entity/EntityType.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/entity/EntityType.java
index aa71c65..9c0f124 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/entity/EntityType.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/entity/EntityType.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.api.submodelelement.entity;
 
 import org.eclipse.basyx.submodel.metamodel.enumhelper.StandardizedLiteralEnum;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/entity/IEntity.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/entity/IEntity.java
index a8c557f..be095a8 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/entity/IEntity.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/entity/IEntity.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.api.submodelelement.entity;
 
 import java.util.Collection;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/event/IBasicEvent.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/event/IBasicEvent.java
index cace411..e35022c 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/event/IBasicEvent.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/event/IBasicEvent.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.api.submodelelement.event;
 
 import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/event/IEvent.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/event/IEvent.java
index 3686e5e..9ec86c6 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/event/IEvent.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/event/IEvent.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.api.submodelelement.event;
 
 import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/operation/IAsyncInvocation.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/operation/IAsyncInvocation.java
new file mode 100644
index 0000000..583d12a
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/operation/IAsyncInvocation.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation;
+
+/**
+ * An AsyncInvocation is used for asynchronously invoking operation
+ * 
+ * @author conradi
+ *
+ */
+public interface IAsyncInvocation {
+	
+	/**
+	 * Gets the result of the async Invocation<br>
+	 * Will block if execution is not finished yet
+	 * 
+	 * @return the result of the Invocation
+	 */
+	public Object getResult();
+	
+	/**
+	 * Gets the status of the async Invocation
+	 * 
+	 * @return true if execution is completed; false otherwise
+	 */
+	public boolean isFinished();
+	
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/operation/IOperation.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/operation/IOperation.java
index c7b32ae..42d850e 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/operation/IOperation.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/operation/IOperation.java
@@ -1,9 +1,19 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation;
 
 import java.util.Collection;
 
 import org.eclipse.basyx.submodel.metamodel.api.IElement;
 import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElement;
 
 /**
  * An operation is a submodel element with input and output variables.
@@ -37,10 +47,42 @@
 	/**
 	 * Invoke operation with given parameter
 	 * 
+	 * 
 	 * @param params
-	 *            Operation parameter
+	 *               Operation parameter
 	 * @return If multiple values are returned, Object is here a list of Objects
 	 * @throws Exception
 	 */
-	public Object invoke(Object... params) throws Exception;
+	public Object invoke(Object... params);
+	
+	/**
+	 * Invoke operation with parameters wrapped as SubmodelElements
+	 * 
+	 * 
+	 * @param params
+	 *               Operation parameters
+	 * @return List of results
+	 * @throws Exception
+	 */
+	public SubmodelElement[] invoke(SubmodelElement... elems);
+
+	/**
+	 * Invoke operation with given parameter asynchronously
+	 * 
+	 * @param params
+	 *               Operation parameter
+	 * @return An IAsyncInvocation
+	 */
+	public IAsyncInvocation invokeAsync(Object... params);
+
+	/**
+	 * Invoke operation with given parameter asynchronously and use a user-defined timeout
+	 * 
+	 * @param timeout
+	 *                The timeout in ms
+	 * @param params
+	 *                Operation parameter
+	 * @return An IAsyncInvocation
+	 */
+	public IAsyncInvocation invokeAsyncWithTimeout(int timeout, Object... params);
 }
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/operation/IOperationVariable.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/operation/IOperationVariable.java
index b7cb183..258a836 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/operation/IOperationVariable.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/operation/IOperationVariable.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation;
 
 import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/relationship/IAnnotatedRelationShipElement.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/relationship/IAnnotatedRelationShipElement.java
deleted file mode 100644
index ca78dbe..0000000
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/relationship/IAnnotatedRelationShipElement.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package org.eclipse.basyx.submodel.metamodel.api.submodelelement.relationship;
-
-import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
-
-/**
- * An annotated relationship element is a relationship element that can be
- * annotated withadditional data elements.
- * 
- * @author schnicke
- *
- */
-public interface IAnnotatedRelationShipElement extends IRelationshipElement {
-	/**
-	 * Annotations that hold for the relationships between the two elements.
-	 * 
-	 * @return
-	 */
-	IReference getAnnotation();
-}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/relationship/IAnnotatedRelationshipElement.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/relationship/IAnnotatedRelationshipElement.java
new file mode 100644
index 0000000..7573d3d
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/relationship/IAnnotatedRelationshipElement.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.metamodel.api.submodelelement.relationship;
+
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.relationship.AnnotatedRelationshipElementValue;
+
+/**
+ * An annotated relationship element is a relationship element that can be
+ * annotated with additional data elements.
+ * 
+ * @author schnicke
+ *
+ */
+public interface IAnnotatedRelationshipElement extends IRelationshipElement {
+	@Override
+	AnnotatedRelationshipElementValue getValue();
+
+	void setValue(AnnotatedRelationshipElementValue value);
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/relationship/IRelationshipElement.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/relationship/IRelationshipElement.java
index 3fc679d..ce976e8 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/relationship/IRelationshipElement.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/relationship/IRelationshipElement.java
@@ -1,7 +1,16 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.api.submodelelement.relationship;
 
-import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
 import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.relationship.RelationshipElementValue;
 
 /**
  * A relationship element is used to define a relationship between two referable
@@ -11,17 +20,14 @@
  *
  */
 public interface IRelationshipElement extends ISubmodelElement {
-	/**
-	 * Gets the first element in the relationship taking the role of the subject.
-	 * 
-	 * @return
-	 */
-	IReference getFirst();
+	
+	@Override
+	RelationshipElementValue getValue();
 
 	/**
-	 * Gets the second element in the relationship taking the role of the object.
+	 * Sets the relationship of the RelationshipElement submodel element
 	 * 
-	 * @return
+	 * @param value
 	 */
-	IReference getSecond();
+	void setValue(RelationshipElementValue value);
 }
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/ConnectedElement.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/ConnectedElement.java
index bed6f3d..a9dcc33 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/ConnectedElement.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/ConnectedElement.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.connected;
 
 import java.util.Map;
@@ -16,7 +25,7 @@
 public class ConnectedElement implements IElement {
 
 	private VABElementProxy proxy;
-	private VABModelMap<Object> cached;
+	protected VABModelMap<Object> cached;
 
 	public VABElementProxy getProxy() {
 		return proxy;
@@ -35,8 +44,8 @@
 	 * @return
 	 */
 	@SuppressWarnings("unchecked")
-	protected VABModelMap<Object> getElemLive() {
-		VABModelMap<Object> map = new VABModelMap<>((Map<String, Object>) getProxy().getModelPropertyValue(""));
+	public VABModelMap<Object> getElemLive() {
+		VABModelMap<Object> map = new VABModelMap<>((Map<String, Object>) getProxy().getValue(""));
 		// update cache
 		cached = map;
 		return map;
@@ -49,7 +58,7 @@
 	 * 
 	 * @return
 	 */
-	protected VABModelMap<Object> getElem() {
+	public VABModelMap<Object> getElem() {
 		if (cached == null) {
 			return getElemLive();
 		} else {
@@ -57,6 +66,11 @@
 		}
 	}
 
+	@Override
+	public String toString() {
+		return getElemLive().toString();
+	}
+
 	protected void throwNotSupportedException() {
 		throw new RuntimeException("Not supported on remote object");
 	}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/ConnectedSubModel.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/ConnectedSubModel.java
deleted file mode 100644
index 5d0a57a..0000000
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/ConnectedSubModel.java
+++ /dev/null
@@ -1,143 +0,0 @@
-package org.eclipse.basyx.submodel.metamodel.connected;
-
-import java.util.Collection;
-import java.util.Map;
-
-import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
-import org.eclipse.basyx.submodel.metamodel.api.dataspecification.IEmbeddedDataSpecification;
-import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
-import org.eclipse.basyx.submodel.metamodel.api.qualifier.IAdministrativeInformation;
-import org.eclipse.basyx.submodel.metamodel.api.qualifier.haskind.ModelingKind;
-import org.eclipse.basyx.submodel.metamodel.api.qualifier.qualifiable.IConstraint;
-import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
-import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
-import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
-import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IDataElement;
-import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
-import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperation;
-import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.ConnectedSubmodelElementFactory;
-import org.eclipse.basyx.submodel.metamodel.map.qualifier.AdministrativeInformation;
-import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasDataSpecification;
-import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasSemantics;
-import org.eclipse.basyx.submodel.metamodel.map.qualifier.Identifiable;
-import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangStrings;
-import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
-import org.eclipse.basyx.submodel.metamodel.map.qualifier.haskind.HasKind;
-import org.eclipse.basyx.submodel.metamodel.map.qualifier.qualifiable.Qualifiable;
-import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElement;
-import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
-import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
-
-
-/**
- * "Connected" implementation of SubModel
- * 
- * @author rajashek
- *
- */
-public class ConnectedSubModel extends ConnectedElement implements ISubModel {
-
-	public ConnectedSubModel(VABElementProxy proxy) {
-		super(proxy);
-	}
-
-	protected KeyElements getKeyElement() {
-		return KeyElements.SUBMODELELEMENT;
-	}
-
-	@SuppressWarnings("unchecked")
-	@Override
-	public IReference getSemanticId() {
-		return Reference.createAsFacade((Map<String, Object>) getElem().get(HasSemantics.SEMANTICID));
-	}
-
-	@Override
-	public IAdministrativeInformation getAdministration() {
-		return AdministrativeInformation.createAsFacade(getElem());
-	}
-
-	@Override
-	public IIdentifier getIdentification() {
-		return Identifiable.createAsFacade(getElem(), getKeyElement()).getIdentification();
-	}
-
-	@Override
-	public Collection<IReference> getDataSpecificationReferences() {
-		return HasDataSpecification.createAsFacade(getElem()).getDataSpecificationReferences();
-	}
-
-	@Override
-	public Collection<IEmbeddedDataSpecification> getEmbeddedDataSpecifications() {
-		return HasDataSpecification.createAsFacade(getElem()).getEmbeddedDataSpecifications();
-	}
-
-	@Override
-	public ModelingKind getModelingKind() {
-		return HasKind.createAsFacade(getElem()).getModelingKind();
-	}
-
-	@Override
-	public String getIdShort() {
-		return (String) getElem().get(Referable.IDSHORT);
-	}
-
-	@Override
-	public String getCategory() {
-		return (String) getElem().get(Referable.CATEGORY);
-	}
-
-	@Override
-	public LangStrings getDescription() {
-		return Referable.createAsFacade(getElem(), getKeyElement()).getDescription();
-	}
-
-	@SuppressWarnings("unchecked")
-	@Override
-	public IReference getParent() {
-		return Reference.createAsFacade((Map<String, Object>) getElem().getPath(Referable.PARENT));
-	}
-	
-	@Override
-	public Collection<IConstraint> getQualifier() {
-		return Qualifiable.createAsFacade(getElem()).getQualifier();
-	}
-
-	@Override
-	public void addSubModelElement(ISubmodelElement element) {
-		if (element instanceof SubmodelElement) {
-			((SubmodelElement) element).setParent(getReference());
-		}
-		
-		if (element instanceof IDataElement) {
-			getProxy().createValue(SubmodelElementProvider.PROPERTIES, element);
-		} else if (element instanceof IOperation) {
-			getProxy().createValue(SubmodelElementProvider.OPERATIONS, element);
-		} else if (element instanceof ISubmodelElement) {
-			getProxy().createValue(SubmodelElementProvider.ELEMENTS, element);
-		}
-	}
-
-	@Override
-	public Map<String, IProperty> getProperties() {
-		return ConnectedSubmodelElementFactory.getProperties(getProxy(), SubmodelElementProvider.PROPERTIES,
-						SubmodelElementProvider.PROPERTIES);
-	}
-
-	@Override
-	public Map<String, IOperation> getOperations() {
-		return ConnectedSubmodelElementFactory.getOperations(getProxy(), SubmodelElementProvider.OPERATIONS,
-				SubmodelElementProvider.OPERATIONS);
-	}
-
-	@Override
-	public Map<String, ISubmodelElement> getSubmodelElements() {
-		return ConnectedSubmodelElementFactory.getConnectedSubmodelElements(getProxy(),
-				SubmodelElementProvider.ELEMENTS, SubmodelElementProvider.ELEMENTS);
-	}
-
-	@Override
-	public IReference getReference() {
-		return Identifiable.createAsFacade(getElem(), getKeyElement()).getReference();
-	}
-}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/ConnectedSubmodel.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/ConnectedSubmodel.java
new file mode 100644
index 0000000..d5c0fa6
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/ConnectedSubmodel.java
@@ -0,0 +1,206 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.metamodel.connected;
+
+import java.util.Collection;
+import java.util.Map;
+
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.api.dataspecification.IEmbeddedDataSpecification;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.submodel.metamodel.api.qualifier.IAdministrativeInformation;
+import org.eclipse.basyx.submodel.metamodel.api.qualifier.haskind.ModelingKind;
+import org.eclipse.basyx.submodel.metamodel.api.qualifier.qualifiable.IConstraint;
+import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperation;
+import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.ConnectedSubmodelElementFactory;
+import org.eclipse.basyx.submodel.metamodel.facade.SubmodelElementMapCollectionConverter;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasDataSpecification;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasSemantics;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Identifiable;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangStrings;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.haskind.HasKind;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.qualifiable.Qualifiable;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
+import org.eclipse.basyx.submodel.restapi.MultiSubmodelElementProvider;
+import org.eclipse.basyx.submodel.restapi.SubmodelProvider;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+import org.eclipse.basyx.vab.modelprovider.VABPathTools;
+
+
+/**
+ * "Connected" implementation of Submodel
+ * 
+ * @author rajashek
+ *
+ */
+public class ConnectedSubmodel extends ConnectedElement implements ISubmodel {
+
+	public ConnectedSubmodel(VABElementProxy proxy) {
+		super(proxy);
+	}
+
+	/**
+	 * Creates a ConnectedSubmodel based on a proxy and an already cached local copy
+	 * 
+	 * @param proxy
+	 * @param localCopy
+	 */
+	public ConnectedSubmodel(VABElementProxy proxy, Submodel localCopy) {
+		super(proxy);
+		cached = localCopy;
+	}
+
+	protected KeyElements getKeyElement() {
+		return KeyElements.SUBMODEL;
+	}
+
+	@Override
+	public IReference getSemanticId() {
+		return HasSemantics.createAsFacade(getElem()).getSemanticId();
+	}
+
+	@Override
+	public IAdministrativeInformation getAdministration() {
+		return Identifiable.createAsFacade(getElem(), getKeyElement()).getAdministration();
+	}
+
+	@Override
+	public IIdentifier getIdentification() {
+		return Identifiable.createAsFacade(getElem(), getKeyElement()).getIdentification();
+	}
+
+	@Override
+	public Collection<IReference> getDataSpecificationReferences() {
+		return HasDataSpecification.createAsFacade(getElem()).getDataSpecificationReferences();
+	}
+
+	@Override
+	public Collection<IEmbeddedDataSpecification> getEmbeddedDataSpecifications() {
+		return HasDataSpecification.createAsFacade(getElem()).getEmbeddedDataSpecifications();
+	}
+
+	@Override
+	public ModelingKind getModelingKind() {
+		return HasKind.createAsFacade(getElem()).getModelingKind();
+	}
+
+	@Override
+	public String getIdShort() {
+		return (String) getElem().get(Referable.IDSHORT);
+	}
+
+	@Override
+	public String getCategory() {
+		return (String) getElem().get(Referable.CATEGORY);
+	}
+
+	@Override
+	public LangStrings getDescription() {
+		return Referable.createAsFacade(getElem(), getKeyElement()).getDescription();
+	}
+
+	@Override
+	public IReference getParent() {
+		return Referable.createAsFacade(getElem(), getKeyElement()).getParent();
+	}
+	
+	@Override
+	public Collection<IConstraint> getQualifiers() {
+		return Qualifiable.createAsFacade(getElem()).getQualifiers();
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public void addSubmodelElement(ISubmodelElement element) {
+		String path = VABPathTools.concatenatePaths(MultiSubmodelElementProvider.ELEMENTS, element.getIdShort());
+
+		if (element instanceof SubmodelElement) {
+			((SubmodelElement) element).setParent(getReference());
+			
+			// Convert "value" in SubmodelElementCollection from Map to Collection
+			if (element instanceof SubmodelElementCollection) {
+				Map<String, Object> converted = SubmodelElementMapCollectionConverter.smElementToMap((Map<String, Object>) element);
+				
+				getProxy().setValue(path, converted);
+				return;
+			}
+		}
+		getProxy().setValue(path, element);
+	}
+
+	@Override
+	public Map<String, IProperty> getProperties() {
+		return ConnectedSubmodelElementFactory.getProperties(getProxy(), MultiSubmodelElementProvider.ELEMENTS,
+						MultiSubmodelElementProvider.ELEMENTS);
+	}
+
+	@Override
+	public Map<String, IOperation> getOperations() {
+		return ConnectedSubmodelElementFactory.getOperations(getProxy(), MultiSubmodelElementProvider.ELEMENTS,
+				MultiSubmodelElementProvider.ELEMENTS);
+	}
+
+	@Override
+	public Map<String, ISubmodelElement> getSubmodelElements() {
+		return ConnectedSubmodelElementFactory.getConnectedSubmodelElements(getProxy(),
+				MultiSubmodelElementProvider.ELEMENTS, MultiSubmodelElementProvider.ELEMENTS);
+	}
+	
+	@SuppressWarnings("unchecked")
+	@Override
+	public Map<String, Object> getValues() {
+		return (Map<String, Object>) getProxy().getValue(SubmodelProvider.VALUES);
+	}
+
+	@Override
+	public IReference getReference() {
+		return Identifiable.createAsFacade(getElem(), getKeyElement()).getReference();
+	}
+
+	/**
+	 * Returns a local copy of the submodel, i.e. a snapshot of the current state.
+	 * <br>
+	 * No changes of this copy are reflected in the remote Submodel
+	 * 
+	 * @return the local copy
+	 */
+	public Submodel getLocalCopy() {
+		return Submodel.createAsFacade(getElem());
+	}
+
+	/**
+	 * Get submodel element by given id
+	 * @param id
+	 * @return specific submodel element
+	 */
+	@SuppressWarnings("unchecked")
+	@Override
+	public ISubmodelElement getSubmodelElement(String id) {
+		Map<String, Object> node =(Map<String, Object>) getProxy().getValue(VABPathTools.concatenatePaths(MultiSubmodelElementProvider.ELEMENTS, id));
+		ISubmodelElement element = ConnectedSubmodelElementFactory.getConnectedSubmodelElement(getProxy(), MultiSubmodelElementProvider.ELEMENTS, id, node);
+		return element;		
+	}
+
+	/**
+	 * Delete a submodel element by given id
+	 * @param id
+	 */
+	@Override
+	public void deleteSubmodelElement(String id) {
+		getProxy().deleteValue(VABPathTools.concatenatePaths(MultiSubmodelElementProvider.ELEMENTS, id));
+	}
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/ConnectedEvent.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/ConnectedEvent.java
index 22856fa..a92532e 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/ConnectedEvent.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/ConnectedEvent.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.connected.submodelelement;
 
 /**
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/ConnectedSubmodelElement.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/ConnectedSubmodelElement.java
index a56d67e..b439740 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/ConnectedSubmodelElement.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/ConnectedSubmodelElement.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.connected.submodelelement;
 
 import java.util.Collection;
@@ -17,6 +26,8 @@
 import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
 import org.eclipse.basyx.submodel.metamodel.map.qualifier.haskind.HasKind;
 import org.eclipse.basyx.submodel.metamodel.map.qualifier.qualifiable.Qualifiable;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElement;
+import org.eclipse.basyx.submodel.restapi.MultiSubmodelElementProvider;
 import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
 
 /**
@@ -54,8 +65,8 @@
 	}
 
 	@Override
-	public Collection<IConstraint> getQualifier() {
-		return Qualifiable.createAsFacade(getElem()).getQualifier();
+	public Collection<IConstraint> getQualifiers() {
+		return Qualifiable.createAsFacade(getElem()).getQualifiers();
 	}
 
 	@Override
@@ -89,4 +100,14 @@
 	public IReference getReference() {
 		return Referable.createAsFacade(getElem(), getKeyElement()).getReference();
 	}
+	
+	@Override
+	public void setValue(Object value) {
+		getProxy().setValue(MultiSubmodelElementProvider.VALUE, value);
+	}
+
+	@Override
+	public SubmodelElement getLocalCopy() {
+		return SubmodelElement.createAsFacade(getElem()).getLocalCopy();
+	}
 }
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/ConnectedSubmodelElementCollection.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/ConnectedSubmodelElementCollection.java
index b4139e3..7a5a23d 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/ConnectedSubmodelElementCollection.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/ConnectedSubmodelElementCollection.java
@@ -1,6 +1,17 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.connected.submodelelement;
 
-import java.util.Collection;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
 import java.util.Map;
 
 import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
@@ -8,6 +19,8 @@
 import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElementCollection;
 import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
 import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperation;
+import org.eclipse.basyx.submodel.metamodel.facade.SubmodelElementMapCollectionConverter;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElement;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
 import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
@@ -24,8 +37,8 @@
 	}
 
 	@Override
-	public Collection<ISubmodelElement> getValue() {
-		return getSubmodelElements().values();
+	public List<ISubmodelElement> getValue() {
+		return Collections.unmodifiableList(new ArrayList<>(getSubmodelElements().values()));
 	}
 
 	@Override
@@ -57,4 +70,52 @@
 	protected KeyElements getKeyElement() {
 		return KeyElements.SUBMODELELEMENTCOLLECTION;
 	}
+	
+	/**
+	 * Get submodel element by given id
+	 * @param id
+	 * @return specific submodel element
+	 */
+	@SuppressWarnings("unchecked")
+	@Override
+	public ISubmodelElement getSubmodelElement(String id) {
+		Map<String, Object> node =(Map<String, Object>) getProxy().getValue(id);
+		ISubmodelElement element = ConnectedSubmodelElementFactory.getConnectedSubmodelElement(getProxy(), "", id, node);
+		return element;			
+	}
+
+	/**
+	 * Delete a submodel element by given id
+	 * @param id
+	 */
+	@Override
+	public void deleteSubmodelElement(String id) {
+		getProxy().deleteValue(id);
+	}
+	
+	/**
+	 * adds a submodel element to the collection
+	 * @param element
+	 */
+	@SuppressWarnings("unchecked")
+	@Override
+	public void addSubmodelElement(ISubmodelElement element) {
+		if (element instanceof SubmodelElement) {
+			((SubmodelElement) element).setParent(getReference());
+
+			// Convert "value" in SubmodelElementCollection from Map to Collection
+			if (element instanceof SubmodelElementCollection) {
+				Map<String, Object> converted = SubmodelElementMapCollectionConverter.smElementToMap((Map<String, Object>) element);
+				getProxy().setValue(element.getIdShort(), converted);
+				return;
+			}
+		}
+		
+		getProxy().setValue(element.getIdShort(), element);
+	}
+
+	@Override
+	public SubmodelElementCollection getLocalCopy() {
+		return SubmodelElementCollection.createAsFacade(getElem()).getLocalCopy();
+	}
 }
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/ConnectedSubmodelElementFactory.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/ConnectedSubmodelElementFactory.java
index c87d8c7..f0bcadd 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/ConnectedSubmodelElementFactory.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/ConnectedSubmodelElementFactory.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.connected.submodelelement;
 
 
@@ -19,17 +28,19 @@
 import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.dataelement.ConnectedReferenceElement;
 import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.event.ConnectedBasicEvent;
 import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.operation.ConnectedOperation;
+import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.relationship.ConnectedAnnotatedRelationshipElement;
 import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.relationship.ConnectedRelationshipElement;
 import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.Blob;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.File;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.MultiLanguageProperty;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.Range;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.ReferenceElement;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.range.Range;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.event.BasicEvent;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.relationship.AnnotatedRelationshipElement;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.relationship.RelationshipElement;
 import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
 import org.eclipse.basyx.vab.modelprovider.VABPathTools;
@@ -56,7 +67,7 @@
 			String collectionPath, String elementPath) {
 		// Query the whole list of elements
 		Collection<Map<String, Object>> mapElemList = (Collection<Map<String, Object>>) rootProxy
-				.getModelPropertyValue(collectionPath);
+				.getValue(collectionPath);
 		// Get the type and idShort for each element and create the corresponding connected variant
 		Map<String, ISubmodelElement> ret = new HashMap<>();
 		for (Map<String, Object> node : mapElemList) {
@@ -80,7 +91,7 @@
 			String collectionPath, String elementPath) {
 		// Query the whole list of elements
 		Collection<Map<String, Object>> mapElemList = (Collection<Map<String, Object>>) rootProxy
-				.getModelPropertyValue(collectionPath);
+				.getValue(collectionPath);
 		// Get the type and idShort for each element and create the corresponding connected variant
 		Collection<ISubmodelElement> ret = new ArrayList<>();
 		for (Map<String, Object> node : mapElemList) {
@@ -99,7 +110,7 @@
 	 * @param elementPath    path in the proxy for accessing single elements by short ids
 	 * @return The connected variant of the requested submodel element
 	 */
-	private static ISubmodelElement getConnectedSubmodelElement(VABElementProxy rootProxy,
+	public static ISubmodelElement getConnectedSubmodelElement(VABElementProxy rootProxy,
 			String elementPath, String idShort, Map<String, Object> mapContent) {
 		String subPath = VABPathTools.concatenatePaths(elementPath, idShort);
 		VABElementProxy proxy = rootProxy.getDeepProxy(subPath);
@@ -117,6 +128,8 @@
 			return new ConnectedRange(proxy);
 		} else if(ReferenceElement.isReferenceElement(mapContent)) {
 			return new ConnectedReferenceElement(proxy);
+		} else if (AnnotatedRelationshipElement.isAnnotatedRelationshipElement(mapContent)) {
+			return new ConnectedAnnotatedRelationshipElement(proxy);
 		} else if (RelationshipElement.isRelationshipElement(mapContent)) {
 			return new ConnectedRelationshipElement(proxy);
 		} else if (Operation.isOperation(mapContent)) {
@@ -141,7 +154,7 @@
 			String elementPath) {
 		// Query the whole list of elements
 		Collection<Map<String, Object>> mapElemList = (Collection<Map<String, Object>>) rootProxy
-				.getModelPropertyValue(collectionPath);
+				.getValue(collectionPath);
 
 		// Get the type and idShort for each operation and create the corresponding connected variant
 		Map<String, IOperation> ret = new HashMap<>();
@@ -169,7 +182,7 @@
 			String elementPath) {
 		// Query the whole list of elements
 		Collection<Map<String, Object>> mapElemList = (Collection<Map<String, Object>>) rootProxy
-				.getModelPropertyValue(collectionPath);
+				.getValue(collectionPath);
 
 		// Get the type and idShort for each operation and create the corresponding connected variant
 		Map<String, IDataElement> ret = new HashMap<>();
@@ -206,7 +219,7 @@
 	public static Map<String, IProperty> getProperties(VABElementProxy rootProxy, String collectionPath,
 			String elementPath) {
 		// Query the whole list of elements
-		Collection<Map<String, Object>> mapElemList = (Collection<Map<String, Object>>) rootProxy.getModelPropertyValue(collectionPath);
+		Collection<Map<String, Object>> mapElemList = (Collection<Map<String, Object>>) rootProxy.getValue(collectionPath);
 
 		// Get the type and idShort for each operation and create the corresponding
 		// connected variant
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedBlob.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedBlob.java
index f2d1b12..102a430 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedBlob.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedBlob.java
@@ -1,6 +1,16 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.connected.submodelelement.dataelement;
 
-import java.util.Map;
+import java.nio.charset.StandardCharsets;
+import java.util.Base64;
 
 import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
 import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IBlob;
@@ -19,13 +29,14 @@
 		super(proxy);		
 	}
 
-	@SuppressWarnings("unchecked")
 	@Override
-	public byte[] getValue() {
-		
-		// FIXME: This is a hack, fix this when API is clear
-		Property value = Property.createAsFacade((Map<String, Object>) getProxy().getModelPropertyValue(Property.VALUE));
-		return ((String) value.get()).getBytes();
+	public String getValue() {
+		Object connectedValue = getProxy().getValue(Property.VALUE);
+		if (connectedValue instanceof String) {
+			return (String) connectedValue;
+		} else {
+			return null;
+		}
 	}
 
 	@Override
@@ -37,5 +48,47 @@
 	protected KeyElements getKeyElement() {
 		return KeyElements.BLOB;
 	}
+
+	@Override
+	public Blob getLocalCopy() {
+		return Blob.createAsFacade(getElem()).getLocalCopy();
+	}
+
+	@Override
+	public void setValue(String value) {
+		if (value instanceof String) {
+			// Assume a Base64 encoded String
+			setValue((Object) value);
+		} else {
+			throw new IllegalArgumentException("Given Object is not a String");
+		}
+	}
+
+
+	@Override
+	public byte[] getByteArrayValue() {
+		String value = getValue();
+		if (value != null) {
+			return Base64.getDecoder().decode(value);
+		} else {
+			return null;
+		}
+	}
+
+	@Override
+	public void setByteArrayValue(byte[] value) {
+		setValue((Object) Base64.getEncoder().encodeToString(value));
+	}
+
+	@Override
+	public String getUTF8String() {
+		return getLocalCopy().getUTF8String();
+	}
+
+	@Override
+	public void setUTF8String(String text) {
+		byte[] byteArray = text.getBytes(StandardCharsets.UTF_8);
+		setByteArrayValue(byteArray);
+	}
 }
 
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedDataElement.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedDataElement.java
index 6c5f6c9..23aacda 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedDataElement.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedDataElement.java
@@ -1,8 +1,18 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.connected.submodelelement.dataelement;
 
 import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
 import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IDataElement;
 import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.ConnectedSubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.DataElement;
 import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
 
 /**
@@ -20,4 +30,14 @@
 	protected KeyElements getKeyElement() {
 		return KeyElements.DATAELEMENT;
 	}
+	
+	@Override
+	public Object getValue() {
+		throw new UnsupportedOperationException("getValue is only possible in specific Element");
+	}
+
+	@Override
+	public DataElement getLocalCopy() {
+		return DataElement.createAsFacade(getElem()).getLocalCopy();
+	}
 }
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedFile.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedFile.java
index 6d443b9..ea8ca78 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedFile.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedFile.java
@@ -1,7 +1,14 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.connected.submodelelement.dataelement;
 
-import java.util.Map;
-
 import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
 import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IFile;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.File;
@@ -19,13 +26,11 @@
 		super(proxy);		
 	}
 
-	@SuppressWarnings("unchecked")
 	@Override
 	public String getValue() {
 		
 		// FIXME: This is a hack, fix this when API is clear
-		Property value = Property.createAsFacade((Map<String, Object>) getProxy().getModelPropertyValue(Property.VALUE));
-		return (String) value.get();
+		return (String) getProxy().getValue(Property.VALUE);
 	}
 
 	@Override
@@ -38,4 +43,13 @@
 		return KeyElements.FILE;
 	}
 
+	@Override
+	public File getLocalCopy() {
+		return File.createAsFacade(getElem()).getLocalCopy();
+	}
+
+	@Override
+	public void setValue(String value) {
+		setValue((Object) value);
+	}
 }
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedMultiLanguageProperty.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedMultiLanguageProperty.java
index e3c4d4b..0e6c0d8 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedMultiLanguageProperty.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedMultiLanguageProperty.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.connected.submodelelement.dataelement;
 
 import java.util.Collection;
@@ -38,4 +47,14 @@
 	protected KeyElements getKeyElement() {
 		return KeyElements.MULTILANGUAGEPROPERTY;
 	}
+
+	@Override
+	public MultiLanguageProperty getLocalCopy() {
+		return MultiLanguageProperty.createAsFacade(getElem()).getLocalCopy();
+	}
+
+	@Override
+	public void setValue(LangStrings value) {
+		setValue((Object) value);
+	}
 }
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedProperty.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedProperty.java
index 8bf18c1..e6124e6 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedProperty.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedProperty.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.connected.submodelelement.dataelement;
 
 import java.util.Map;
@@ -6,10 +15,9 @@
 import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
 import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
 import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.MultiLanguageProperty;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetypedef.PropertyValueTypeDefHelper;
-import org.eclipse.basyx.vab.exception.provider.ProviderException;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueTypeHelper;
 import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
 
 /**
@@ -26,31 +34,19 @@
 	}
 
 	@Override
-	public Object get() throws Exception {
-		return retrieveObject();
-	}
-
-	@Override
-	public void set(Object newValue) throws ProviderException {
-		getProxy().setModelPropertyValue(Property.VALUE, newValue);
-	}
-
-	@SuppressWarnings({ "unchecked" })
-	@Override
-	public String getValueType() {
-		Object o = getProxy().getModelPropertyValue("");
-		return PropertyValueTypeDefHelper.readTypeDef(((Map<String, Object>) o).get(Property.VALUETYPE)).toString();
+	public ValueType getValueType() {
+		return ValueTypeHelper.readTypeDef(getElem().getPath(Property.VALUETYPE));
 	}
 
 	@SuppressWarnings("unchecked")
 	@Override
 	public IReference getValueId() {
-		return Reference.createAsFacade((Map<String, Object>) getProxy().getModelPropertyValue(MultiLanguageProperty.VALUEID));
+		return Reference.createAsFacade((Map<String, Object>) getElem().getPath(Property.VALUEID));
 	}
 
 	@SuppressWarnings("unchecked")
 	protected <T> T retrieveObject() {
-		return (T) ((Map<String, Object>) getProxy().getModelPropertyValue(Property.VALUE)).get(Property.VALUE);
+		return (T) getProxy().getValue(Property.VALUE);
 	}
 	
 	@Override
@@ -58,4 +54,23 @@
 		return KeyElements.PROPERTY;
 	}
 
+	@Override
+	public Object getValue() {
+		Object value =  retrieveObject();
+		if(value instanceof String) {
+			return ValueTypeHelper.getJavaObject(value, getValueType());
+		}else {
+			return value;
+		}
+	}
+	
+	@Override
+	public void setValue(Object value) {
+		getProxy().setValue(Property.VALUE, ValueTypeHelper.prepareForSerialization(value));
+	}
+
+	@Override
+	public Property getLocalCopy() {
+		return Property.createAsFacade(getElem()).getLocalCopy();
+	}
 }
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedRange.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedRange.java
index ff97641..d2a1d1d 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedRange.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedRange.java
@@ -1,8 +1,23 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.connected.submodelelement.dataelement;
 
+import java.util.Map;
+
 import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
 import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IRange;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.Range;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueTypeHelper;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.range.Range;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.range.RangeValue;
+import org.eclipse.basyx.submodel.restapi.MultiSubmodelElementProvider;
 import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
 
 /**
@@ -17,22 +32,59 @@
 	}
 
 	@Override
-	public String getValueType() {
-		return (String) getElem().getPath(Range.VALUETYPE);
+	public ValueType getValueType() {
+		return ValueTypeHelper.readTypeDef(getElem().getPath(Range.VALUETYPE));
 	}
 
 	@Override
 	public Object getMin() {
-		return getElem().getPath(Range.MIN);
+		Object min = getElem().getPath(Range.MIN);
+		return ValueTypeHelper.getJavaObject(min, getValueType());
 	}
 
 	@Override
 	public Object getMax() {
-		return getElem().getPath(Range.MAX);
+		Object max = getElem().getPath(Range.MAX);
+		return ValueTypeHelper.getJavaObject(max, getValueType());
 	}
 
 	@Override
 	protected KeyElements getKeyElement() {
 		return KeyElements.RANGE;
 	}
-}
\ No newline at end of file
+
+	@Override
+	public RangeValue getValue() {
+		return new RangeValue(getMin(), getMax());
+	}
+	
+	@SuppressWarnings("unchecked")
+	@Override
+	public void setValue(Object value) {
+		if(RangeValue.isRangeValue(value)) {
+			RangeValue rangeValue = RangeValue.createAsFacade((Map<String, Object>) value);
+			setValue(rangeValue);
+		} else {
+			throw new IllegalArgumentException("Given object " + value + " is not a RangeValue");
+		}
+	}
+
+	@Override
+	public Range getLocalCopy() {
+		return Range.createAsFacade(getElem()).getLocalCopy();
+	}
+
+	@Override
+	public void setValue(RangeValue rangeValue) {
+		Object minRaw = rangeValue.getMin();
+		Object maxRaw = rangeValue.getMax();
+
+		RangeValue prepared = new RangeValue(
+				ValueTypeHelper.prepareForSerialization(minRaw),
+				ValueTypeHelper.prepareForSerialization(maxRaw)
+			);
+				
+		
+		getProxy().setValue(MultiSubmodelElementProvider.VALUE, prepared);
+	}
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedReferenceElement.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedReferenceElement.java
index 036c884..f5c4a40 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedReferenceElement.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedReferenceElement.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.connected.submodelelement.dataelement;
 
 import java.util.Map;
@@ -6,6 +15,7 @@
 import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
 import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IReferenceElement;
 import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.ReferenceElement;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
 import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
 
@@ -30,4 +40,13 @@
 		return KeyElements.REFERENCEELEMENT;
 	}
 
-}
\ No newline at end of file
+	@Override
+	public ReferenceElement getLocalCopy() {
+		return ReferenceElement.createAsFacade(getElem()).getLocalCopy();
+	}
+
+	@Override
+	public void setValue(IReference value) {
+		setValue((Object) value);
+	}
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/event/ConnectedBasicEvent.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/event/ConnectedBasicEvent.java
index 5c1386f..f38d274 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/event/ConnectedBasicEvent.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/event/ConnectedBasicEvent.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.connected.submodelelement.event;
 
 import java.util.Map;
@@ -31,4 +40,14 @@
 	protected KeyElements getKeyElement() {
 		return KeyElements.BASICEVENT;
 	}
+
+	@Override
+	public IReference getValue() {
+		return getObserved();
+	}
+
+	@Override
+	public BasicEvent getLocalCopy() {
+		return BasicEvent.createAsFacade(getElem()).getLocalCopy();
+	}
 }
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/operation/ConnectedAsyncInvocation.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/operation/ConnectedAsyncInvocation.java
new file mode 100644
index 0000000..11365be
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/operation/ConnectedAsyncInvocation.java
@@ -0,0 +1,154 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.metamodel.connected.submodelelement.operation;
+
+import java.util.Map;
+
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IAsyncInvocation;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.OperationExecutionErrorException;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.OperationExecutionTimeoutException;
+import org.eclipse.basyx.submodel.restapi.OperationProvider;
+import org.eclipse.basyx.submodel.restapi.operation.CallbackResponse;
+import org.eclipse.basyx.submodel.restapi.operation.ExecutionState;
+import org.eclipse.basyx.submodel.restapi.operation.InvocationRequest;
+import org.eclipse.basyx.submodel.restapi.operation.InvocationResponse;
+import org.eclipse.basyx.vab.exception.provider.ProviderException;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+import org.eclipse.basyx.vab.modelprovider.VABPathTools;
+
+/**
+ * Connected variant of IAsyncInvocation
+ * 
+ * @author conradi
+ *
+ */
+public class ConnectedAsyncInvocation implements IAsyncInvocation {
+
+	private String operationId;
+	private String requestId;
+	
+	private VABElementProxy proxy;
+	
+	private Object result = null;
+	private boolean resultRetrieved = false;
+	
+	@SuppressWarnings("unchecked")
+	public ConnectedAsyncInvocation(VABElementProxy proxy, String operationId, InvocationRequest request) {
+		this.proxy = proxy;
+		this.operationId = operationId;
+		CallbackResponse response = CallbackResponse.createAsFacade((Map<String, Object>) proxy.invokeOperation(Operation.INVOKE + OperationProvider.ASYNC, request));
+		requestId = response.getRequestId();
+	}
+	
+	@Override
+	public Object getResult() {
+		// Wait for Operation to finish
+		while (!isFinished()) {
+			try {
+				Thread.sleep(50);
+			} catch (InterruptedException e) {
+			}
+		}
+		
+		// Side-effect of isFinished is querying the result.
+		// Thus, it can be assumed, the the result will be available here
+
+		if (result instanceof Exception) {
+			throw new OperationExecutionErrorException("Exception while executing Invocation '"
+					+ requestId + "' of Operation '" + operationId + "'");
+		} else if (ExecutionState.FAILED == result) {
+			throw new OperationExecutionErrorException("Exception while executing Invocation '" + requestId
+					+ "' of Operation '" + operationId + "'; Operation failed");
+		} else if (ExecutionState.TIMEOUT == result) {
+			throw new OperationExecutionTimeoutException(
+					"Invocation '" + requestId + "' of Operation '" + operationId + "' timed out");
+		} else {
+			return result;
+		}
+	}
+	
+	/**
+	 * Queries the operation with the connected proxy to see, if the result is already finished
+	 */
+	@Override
+	public boolean isFinished() {
+		if (resultRetrieved) {
+			// If the result was already retrieved the Operation is done
+			return true;
+		}
+
+		retrieveResultDirectly();
+		return resultRetrieved;
+	}
+
+	@SuppressWarnings("unchecked")
+	private void retrieveResultDirectly() {
+		// 1. Retrieve InvocationResponse from proxy
+		Object responseObj = null;
+		try {
+			 responseObj = proxy.getValue(getListPath());
+		} catch (ProviderException e) {
+			// As the Submodel-API does not specify a request to ask whether
+			// the operation is finished, it has to be done via the retrieval of the value.
+			// If the execution resulted in an Exception this Exception would be thrown here
+			// -> if a ProviderException with a RuntimeException as cause is thrown,
+			// the Operation is finished.
+			if (e.getCause() instanceof RuntimeException) {
+				resultRetrieved = true;
+				result = e;
+			} else {
+				// If it is something else -> rethrow it
+				throw e;
+			}
+		}
+
+		// 2. Cast response to InvocationResponse
+		InvocationResponse response = null;
+		if ( responseObj instanceof InvocationResponse ) {
+			response = (InvocationResponse) responseObj;
+		} else if ( result instanceof Map<?, ?> ) {
+			response = InvocationResponse.createAsFacade((Map<String, Object>) result);
+		} else {
+			// got no valid InvocationResponse
+			throw new ProviderException("Response for requestId " + requestId + " invalid!");
+		}
+
+		// 3. Transform to direct result
+		switch (response.getExecutionState()) {
+			case COMPLETED:
+				// Finished => set internal state
+				resultRetrieved = true;
+				result = response.getFirstOutput();
+				break;
+			case FAILED:
+			case TIMEOUT:
+				// Finished, but no result => set internal state
+				resultRetrieved = true;
+				result = response.getExecutionState();
+				break;
+			default:
+				// Not finished, yet, result hasn't been retrieved
+		}
+	}
+
+	public String getRequestId() {
+		return requestId;
+	}
+
+	public String getOperationId() {
+		return operationId;
+	}
+	
+	private String getListPath() {
+		return VABPathTools.concatenatePaths(OperationProvider.INVOCATION_LIST, requestId);
+	}
+
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/operation/ConnectedOperation.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/operation/ConnectedOperation.java
index cd5bb41..4c2e6b3 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/operation/ConnectedOperation.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/operation/ConnectedOperation.java
@@ -1,17 +1,36 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.connected.submodelelement.operation;
 
+import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
-import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
 import java.util.Map;
+import java.util.UUID;
+import java.util.stream.Collectors;
 
 import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
 import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperation;
 import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperationVariable;
 import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.ConnectedSubmodelElement;
 import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElement;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetypedef.PropertyValueTypeDefHelper;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.OperationVariable;
+import org.eclipse.basyx.submodel.restapi.operation.InvocationRequest;
+import org.eclipse.basyx.submodel.restapi.operation.InvocationResponse;
+import org.eclipse.basyx.vab.exception.provider.WrongNumberOfParametersException;
 import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
 
 /**
@@ -21,6 +40,9 @@
  *
  */
 public class ConnectedOperation extends ConnectedSubmodelElement implements IOperation {
+	// Default timeout for asynchronous operation calls
+	public static final int DEFAULT_ASYNC_TIMEOUT = Operation.DEFAULT_ASYNC_TIMEOUT;
+
 	public ConnectedOperation(VABElementProxy proxy) {
 		super(proxy);
 	}
@@ -41,28 +63,105 @@
 	}
 
 	/**
-	 * Invoke a remote operation TODO C# includes idShort
+	 * Invoke a remote operation
 	 */
+	@Override
+	public Object invoke(Object... params) {
+		// Wrap simple params
+		SubmodelElement[] wrapper = createElementWrapper(params);
+
+		// Invoke with submodel elements
+		SubmodelElement[] result = invoke(wrapper);
+
+		// Unwrap result wrapper
+		return unwrapResult(result);
+	}
+	
 	@SuppressWarnings("unchecked")
 	@Override
-	public Object invoke(Object... params) throws Exception {
+	public SubmodelElement[] invoke(SubmodelElement... elems) {
+		// Create request
+		InvocationRequest request = createInvocationRequest(DEFAULT_ASYNC_TIMEOUT, elems);
 
-		// Wrap parameter with valuetype information
+		// Invoke the operation
+		Object responseObj = getProxy().invokeOperation(Operation.INVOKE, request);
+		InvocationResponse response = InvocationResponse.createAsFacade((Map<String, Object>) responseObj);
+
+		// Extract the output elements
+		Collection<IOperationVariable> outputArguments = response.getOutputArguments();
+		List<ISubmodelElement> elements = outputArguments.stream().map(IOperationVariable::getValue)
+				.collect(Collectors.toList());
+
+		// Cast them to an array
+		SubmodelElement[] result = new SubmodelElement[elements.size()];
+		elements.toArray(result);
+		return result;
+	}
+
+	private InvocationRequest createInvocationRequest(int timeout, SubmodelElement... elems) {
+		// Wrap parameters in operation variables
+		Collection<IOperationVariable> inputArguments = Arrays.asList(elems).stream().map(OperationVariable::new)
+				.collect(Collectors.toList());
+		// Generate random request id
+		String requestId = UUID.randomUUID().toString();
+
+		// Create invokation request
+		return new InvocationRequest(requestId, new ArrayList<>(), inputArguments, timeout);
+	}
+
+	private SubmodelElement[] createElementWrapper(Object... params) {
+		Collection<IOperationVariable> inputVariables = getInputVariables();
+		if (inputVariables.size() != params.length) {
+			throw new WrongNumberOfParametersException(getIdShort(), inputVariables, params);
+		}
+
+		// Copy parameter values into SubmodelElements according to InputVariables
+		SubmodelElement[] ret = new SubmodelElement[params.length];
+		Iterator<IOperationVariable> iterator = inputVariables.iterator();
 		int i = 0;
-		for (Object param : params) {
-			HashMap<String, Object> valueWrapper = new HashMap<>();
-			valueWrapper.put(Property.VALUETYPE, PropertyValueTypeDefHelper.getTypeWrapperFromObject(param));
-			valueWrapper.put(Property.VALUE, param);
-
-			params[i] = valueWrapper;
+		while (iterator.hasNext()) {
+			IOperationVariable matchedInput = iterator.next();
+			ISubmodelElement inputElement = matchedInput.getValue();
+			SubmodelElement copy = inputElement.getLocalCopy();
+			copy.setValue(params[i]);
+			ret[i] = copy;
 			i++;
 		}
 
-		// Invoke operation passing an empty string, since the used proxy already points
-		// to the operation
-		Object result = getProxy().invokeOperation("", params);
+		return ret;
+	}
 
-		// Unwrap result value
+	@Override
+	public ConnectedAsyncInvocation invokeAsync(Object... params) {
+		SubmodelElement[] smElements = createElementWrapper(params);
+		InvocationRequest request = createInvocationRequest(DEFAULT_ASYNC_TIMEOUT, smElements);
+		return new ConnectedAsyncInvocation(getProxy(), getIdShort(), request);
+	}
+	
+	@Override
+	public ConnectedAsyncInvocation invokeAsyncWithTimeout(int timeout, Object... params) {
+		SubmodelElement[] smElements = createElementWrapper(params);
+		InvocationRequest request = createInvocationRequest(timeout, smElements);
+		return new ConnectedAsyncInvocation(getProxy(), getIdShort(), request);
+	}
+
+	@Override
+	protected KeyElements getKeyElement() {
+		return KeyElements.OPERATION;
+	}
+	
+	@Override
+	public Object getValue() {
+		throw new UnsupportedOperationException("An Operation has no value");
+	}
+
+	@Override
+	public void setValue(Object value) {
+		throw new UnsupportedOperationException("An Operation has no value");
+	}
+	
+	@SuppressWarnings("unchecked")
+	private Object unwrapResult(Object result) {
 		if (result instanceof Collection<?>) {
 			Collection<Object> coll = (Collection<Object>) result;
 			if (coll.isEmpty()) {
@@ -72,16 +171,20 @@
 			if (resultWrapper instanceof Map<?, ?>) {
 				Map<String, Object> map = (Map<String, Object>) resultWrapper;
 				if (map.get(Referable.IDSHORT).equals("Response") && map.get(Property.VALUE) != null) {
-					result = map.get(Property.VALUE);
+					return map.get(Property.VALUE);
 				}
 			}
+		} else if (result instanceof SubmodelElement[]) {
+			SubmodelElement[] arr = (SubmodelElement[]) result;
+			if (arr.length > 0 && arr[0] instanceof Map<?, ?>) {
+				return arr[0].getValue();
+			}
 		}
-
 		return result;
 	}
-	
+
 	@Override
-	protected KeyElements getKeyElement() {
-		return KeyElements.OPERATION;
+	public Operation getLocalCopy() {
+		return Operation.createAsFacade(getElem()).getLocalCopy();
 	}
 }
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/relationship/ConnectedAnnotatedRelationshipElement.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/relationship/ConnectedAnnotatedRelationshipElement.java
new file mode 100644
index 0000000..6a8133c
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/relationship/ConnectedAnnotatedRelationshipElement.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.metamodel.connected.submodelelement.relationship;
+
+import java.util.Map;
+
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.relationship.IAnnotatedRelationshipElement;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.relationship.AnnotatedRelationshipElementValue;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+
+/**
+ * "Connected" implementation of AnnotatedRelationshipElement
+ * 
+ * @author schnicke, conradi
+ *
+ */
+public class ConnectedAnnotatedRelationshipElement extends ConnectedRelationshipElement implements IAnnotatedRelationshipElement {
+
+	public ConnectedAnnotatedRelationshipElement(VABElementProxy proxy) {
+		super(proxy);
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public AnnotatedRelationshipElementValue getValue() {
+		Object obj = getProxy().getValue(Property.VALUE);
+
+		return AnnotatedRelationshipElementValue.createAsFacade((Map<String, Object>) obj);
+	}
+
+	@Override
+	public void setValue(AnnotatedRelationshipElementValue value) {
+		setValue((Object) value);
+	}
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/relationship/ConnectedRelationshipElement.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/relationship/ConnectedRelationshipElement.java
index 4ccb2e0..735ae6f 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/relationship/ConnectedRelationshipElement.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/relationship/ConnectedRelationshipElement.java
@@ -1,13 +1,22 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.connected.submodelelement.relationship;
 
 import java.util.Map;
 
-import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
 import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
 import org.eclipse.basyx.submodel.metamodel.api.submodelelement.relationship.IRelationshipElement;
 import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.ConnectedSubmodelElement;
-import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.relationship.RelationshipElement;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.relationship.RelationshipElementValue;
 import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
 
 /**
@@ -20,31 +29,27 @@
 	public ConnectedRelationshipElement(VABElementProxy proxy) {
 		super(proxy);
 	}
-
-	public void setFirst(IReference first) {
-		getProxy().setModelPropertyValue(RelationshipElement.FIRST, first);
-
-	}
-
-	@SuppressWarnings("unchecked")
-	@Override
-	public IReference getFirst() {
-		return Reference.createAsFacade((Map<String, Object>) getElem().getPath(RelationshipElement.FIRST));
-	}
-
-	public void setSecond(IReference second) {
-		getProxy().setModelPropertyValue(RelationshipElement.SECOND, second);
-
-	}
-
-	@SuppressWarnings("unchecked")
-	@Override
-	public IReference getSecond() {
-		return Reference.createAsFacade((Map<String, Object>) getElem().getPath(RelationshipElement.SECOND));
-	}
 	
 	@Override
 	protected KeyElements getKeyElement() {
 		return KeyElements.RELATIONSHIPELEMENT;
 	}
+	
+	@SuppressWarnings("unchecked")
+	@Override
+	public RelationshipElementValue getValue() {
+		Object obj = getProxy().getValue(Property.VALUE);
+
+		return RelationshipElementValue.createAsFacade((Map<String, Object>) obj);
+	}
+
+	@Override
+	public RelationshipElement getLocalCopy() {
+		return RelationshipElement.createAsFacade(getElem()).getLocalCopy();
+	}
+
+	@Override
+	public void setValue(RelationshipElementValue value) {
+		setValue((Object) value);
+	}
 }
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/enumhelper/StandardizedLiteralEnum.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/enumhelper/StandardizedLiteralEnum.java
index bad3b4d..c3293b5 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/enumhelper/StandardizedLiteralEnum.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/enumhelper/StandardizedLiteralEnum.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.enumhelper;
 
 /**
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/enumhelper/StandardizedLiteralEnumHelper.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/enumhelper/StandardizedLiteralEnumHelper.java
index 2f32a25..48dde83 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/enumhelper/StandardizedLiteralEnumHelper.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/enumhelper/StandardizedLiteralEnumHelper.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.enumhelper;
 
 import com.google.common.base.Strings;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/facade/SubmodelElementMapCollectionConverter.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/facade/SubmodelElementMapCollectionConverter.java
new file mode 100644
index 0000000..56181c1
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/facade/SubmodelElementMapCollectionConverter.java
@@ -0,0 +1,197 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.metamodel.facade;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.facade.submodelelement.SubmodelElementFacadeFactory;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+
+
+/**
+ * This class provides the functionality to convert the
+ * smElements of a Submodel/SubmodelElementCollection from a Collection to a Map and vice versa.<br>
+ * The given Submodel/Map is not changed.<br>
+ * This is necessary, because internally smElements are represented as Map and externally as Collection.
+ * 
+ * @author conradi
+ *
+ */
+public class SubmodelElementMapCollectionConverter {
+	
+	
+	/**
+	 * Builds a Submodel from a given Map.<br>
+	 * Converts the Submodel.SUBMODELELEMENT entry of a Map to a Map<IdShort, SMElement>.<br>
+	 * Creates Facades for all smElements.
+	 * 
+	 * @param submodel a Map representing the Submodel to be converted.
+	 * @return a new Submodel made from the given Map with the smElements as Map
+	 */
+	public static Submodel mapToSM(Map<String, Object> submodel) {
+		
+		// Put the content of the Map into a SM and replace its smElements with the new Map of smElements
+		Submodel ret = new Submodel();
+		ret.setMap(submodel);
+		
+		Object smElements = submodel.get(Submodel.SUBMODELELEMENT);
+		
+		ret.put(Submodel.SUBMODELELEMENT, convertCollectionToIDMap(smElements));
+		
+		return ret;
+	}
+	
+	/**
+	 * Converts a given Submodel to a Map<br>
+	 * Converts the Submodel.SUBMODELELEMENT entry of a Submodel to a Collection.<br>
+	 * 
+	 * @param submodel the Submodel to be converted.
+	 * @return a Map made from the given Submodel containing the smElements as Collection.
+	 */
+	@SuppressWarnings("unchecked")
+	public static Map<String, Object> smToMap(Submodel submodel) {		
+		
+		// Get the smElements Map from the given Submodel
+		Map<String, ISubmodelElement> smElements = submodel.getSubmodelElements();
+		
+		// Put the Entries of the SM in a new Map
+		Map<String, Object> ret = new HashMap<>();
+		ret.putAll(submodel);
+		
+		// Feed all contained smElements through smElementToMap to deal with smElemCollections
+		List<Map<String, Object>> newElements = smElements.values().stream()
+				.map(e -> smElementToMap((Map<String, Object>) e)).collect(Collectors.toList());
+		
+		// Replace the smElements Map with the Collection of Elements
+		ret.put(Submodel.SUBMODELELEMENT, newElements);
+		
+		return ret;
+	}
+
+	
+	/**
+	 * Builds a SubmodelElementCollection from a given Map.<br>
+	 * Converts the Property.VALUE entry of a Map to a Map<IdShort, SMElement>.<br>
+	 * Creates Facades for all smElements.
+	 * 
+	 * @param smECollection a Map representing the SubmodelElementCollection to be converted.
+	 * @return a new SubmodelElementCollection made from the given Map with the smElements as Map
+	 */
+	public static SubmodelElementCollection mapToSmECollection(Map<String, Object> smECollection) {
+		
+		// Put the content of the Map into a SM and replace its smElements with the new Map of smElements
+		SubmodelElementCollection ret = new SubmodelElementCollection();
+		ret.setMap(smECollection);
+		
+		Object smElements = smECollection.get(Property.VALUE);
+		
+		ret.put(Property.VALUE, convertCollectionToIDMap(smElements));
+		
+		return ret;
+	}
+	
+	/**
+	 * Converts a given SubmodelElementCollection to a Map<br>
+	 * Converts the Property.VALUE entry of a SubmodelElementCollection to a Collection.<br>
+	 * If given Element is not a SubmodelElementCollection it will be returned unchanged.
+	 * 
+	 * @param smElement the SubmodelElement to be converted.
+	 * @return a Map made from the given SubmodelElement.
+	 */
+	public static Map<String, Object> smElementToMap(Map<String, Object> smElement) {		
+		
+		if(!SubmodelElementCollection.isSubmodelElementCollection((Map<String, Object>) smElement)) {
+			return (Map<String, Object>) smElement;
+		}
+		
+		// Put the Entries of the SM in a new Map
+		Map<String, Object> ret = new HashMap<>();
+		ret.putAll(smElement);
+		
+		ret.put(Property.VALUE, convertIDMapToCollection(smElement.get(Property.VALUE)));
+		
+		return ret;
+	}
+	
+	
+	/**
+	 * Converts a given smElement Collection/Map to a Map<idShort, smElement>. 
+	 * 
+	 * @param smElements the smElements to be converted
+	 * @return a Map<idSHort, smElement>
+	 */
+	@SuppressWarnings("unchecked")
+	public static Map<String, Object> convertCollectionToIDMap(Object smElements) {
+		Map<String, Object> smElementsMap = new HashMap<>();
+		
+		if(smElements == null) {
+			// if null was given, return an empty Map
+			return smElementsMap;
+		}
+		
+		// SubmodelElemets can be given as Map, Set or List
+		// If it is a Set or List, convert it to a Map first
+		if(smElements instanceof Collection<?>) {
+			Collection<Object> smElementsSet = (Collection<Object>) smElements;
+			for (Object o: smElementsSet) {
+				Map<String, Object> smElement = (Map<String, Object>) o;
+				String id = (String) smElement.get(Referable.IDSHORT);
+				smElementsMap.put(id, smElement);
+			}
+		} else if(smElements instanceof Map<?, ?>){
+			smElementsMap = (Map<String, Object>) smElements;
+		} else {
+			throw new RuntimeException("Elements must be given as Map or Collection");
+		}
+		
+		// Iterate through all SubmodelElements and create Facades for them
+		smElementsMap.replaceAll((id, smElement) ->
+			SubmodelElementFacadeFactory.createSubmodelElement((Map<String, Object>) smElement));
+		
+		return smElementsMap;
+	}
+	
+	
+	/**
+	 * Converts a given Map<idShort, smElement> to a smElement Collection. 
+	 * 
+	 * @param smElements the smElements to be converted
+	 * @return Collection<smElement>
+	 */
+	@SuppressWarnings("unchecked")
+	public static Collection<Map<String, Object>> convertIDMapToCollection(Object map) {
+		Collection<Object> smElements = null;
+		
+		// Check if the contained value is a Map or a Collection
+		if(map instanceof Collection<?>) {
+			// It it is a Collection proceed, as there could be nested Collections that need conversion
+			smElements = (Collection<Object>) map;
+		} else if(map instanceof Map<?, ?>) {
+			smElements = ((Map<String, Object>) map).values();
+		} else {
+			throw new RuntimeException("The SubmodelElementCollection contains neither a Collection nor a Map as value.");
+		}
+		
+		// Feed all contained smElements recursively through smElementToMap again to deal with nested smElemCollections
+		List<Map<String, Object>> newElements = smElements.stream()
+				.map(e -> smElementToMap((Map<String, Object>) e)).collect(Collectors.toList());
+		
+		return newElements;
+	}
+	
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/facade/SubmodelFacadeCustomSemantics.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/facade/SubmodelFacadeCustomSemantics.java
index a0c3714..5f8053a 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/facade/SubmodelFacadeCustomSemantics.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/facade/SubmodelFacadeCustomSemantics.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.facade;
 
 import java.util.Collection;
@@ -7,7 +16,7 @@
 import org.eclipse.basyx.submodel.metamodel.api.qualifier.haskind.ModelingKind;
 import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
 import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyType;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
 import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasDataSpecification;
 import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasSemantics;
 import org.eclipse.basyx.submodel.metamodel.map.qualifier.Identifiable;
@@ -28,7 +37,7 @@
  * @author kuhn
  *
  */
-public class SubmodelFacadeCustomSemantics extends SubModel {
+public class SubmodelFacadeCustomSemantics extends Submodel {
 	/**
 	 * Constructor without arguments - create a sub model with all meta properties empty / set to default values
 	 */
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/facade/SubmodelFacadeIRDISemantics.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/facade/SubmodelFacadeIRDISemantics.java
index 4e9b53a..e4579a1 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/facade/SubmodelFacadeIRDISemantics.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/facade/SubmodelFacadeIRDISemantics.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.facade;
 
 import java.util.Collection;
@@ -7,7 +16,7 @@
 import org.eclipse.basyx.submodel.metamodel.api.qualifier.haskind.ModelingKind;
 import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
 import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyType;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
 import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasDataSpecification;
 import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasSemantics;
 import org.eclipse.basyx.submodel.metamodel.map.qualifier.Identifiable;
@@ -25,7 +34,7 @@
  * @author kuhn
  *
  */
-public class SubmodelFacadeIRDISemantics extends SubModel {
+public class SubmodelFacadeIRDISemantics extends Submodel {
 
 	/**
 	 * Constructor without arguments - create a sub model with all meta properties
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/facade/SubmodelValuesHelper.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/facade/SubmodelValuesHelper.java
new file mode 100644
index 0000000..8bf2b52
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/facade/SubmodelValuesHelper.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.metamodel.facade;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangStrings;
+
+/**
+ * Helperclass for getting the /values Map from a Submodel.
+ * 
+ * @author conradi
+ *
+ */
+public class SubmodelValuesHelper {
+
+	/**
+	 * Gets the Values from a Submodel
+	 * 
+	 * @param sm the Submodel to get the values from.
+	 * @return A Map mapping idShort to the value of the SubmodelElement
+	 */
+	@SuppressWarnings("unchecked")
+	public static Map<String, Object> getSubmodelValue(Submodel sm) {
+		Map<String, ISubmodelElement> elements = sm.getSubmodelElements();
+		
+		return (Map<String, Object>) handleValue(elements.values());
+	}
+	
+	
+	@SuppressWarnings("unchecked")
+	private static Object handleValue(Object value) {
+		// Check if it is a collection but not a LangStrings (is internally also a Collection)
+		if (value instanceof Collection<?> && !(value instanceof LangStrings)) {
+			return handleValueCollection((Collection<ISubmodelElement>) value);
+		} else {
+			// The value is not a collection -> return it as is
+			return value;
+		}
+	}
+
+
+	private static Map<String, Object> handleValueCollection(Collection<ISubmodelElement> collection) {
+		Map<String, Object> ret = new HashMap<>();
+		for(ISubmodelElement element: collection) {
+			try {
+				ret.put(element.getIdShort(), handleValue(element.getValue()));
+			} catch (UnsupportedOperationException e) {
+				// this Element has no value (e.g. an Operation)
+				// -> just ignore it
+			}
+		}
+		return ret;
+	}
+	
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/facade/submodelelement/SubmodelElementFacadeFactory.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/facade/submodelelement/SubmodelElementFacadeFactory.java
index d68e4b2..06c615e 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/facade/submodelelement/SubmodelElementFacadeFactory.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/facade/submodelelement/SubmodelElementFacadeFactory.java
@@ -1,19 +1,28 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.facade.submodelelement;
 
 import java.util.Map;
 
 import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
-import org.eclipse.basyx.submodel.metamodel.map.modeltype.ModelType;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.Blob;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.File;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.MultiLanguageProperty;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.Range;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.ReferenceElement;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.range.Range;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.entity.Entity;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.event.BasicEvent;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.relationship.AnnotatedRelationshipElement;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.relationship.RelationshipElement;
 
 /**
@@ -31,34 +40,34 @@
 	 * @return the actual of the given SubmodelElement map created as facade
 	 */
 	public static ISubmodelElement createSubmodelElement(Map<String, Object> submodelElement) {
-		String type = ModelType.createAsFacade(submodelElement).getName();
-		
-		switch (type) {
-			case Property.MODELTYPE:
-				return Property.createAsFacade(submodelElement);
-			case BasicEvent.MODELTYPE:
-				return BasicEvent.createAsFacade(submodelElement);
-			case MultiLanguageProperty.MODELTYPE:
-				return MultiLanguageProperty.createAsFacade(submodelElement);
-			case Range.MODELTYPE:
-				return Range.createAsFacade(submodelElement);
-			case Entity.MODELTYPE:
-				return Entity.createAsFacade(submodelElement);
-			case File.MODELTYPE:
-				return File.createAsFacade(submodelElement);
-			case Blob.MODELTYPE:
-				return Blob.createAsFacade(submodelElement);
-			case ReferenceElement.MODELTYPE:
-				return ReferenceElement.createAsFacade(submodelElement);
-			case SubmodelElementCollection.MODELTYPE:
-				return SubmodelElementCollection.createAsFacade(submodelElement);
-			case RelationshipElement.MODELTYPE:
-				return RelationshipElement.createAsFacade(submodelElement);
-			case Operation.MODELTYPE:
-				return Operation.createAsFacade(submodelElement);
-			default:
-				throw new RuntimeException("Can not create a submodel element from given map");
+		if (Property.isProperty(submodelElement)) {
+			return Property.createAsFacade(submodelElement);
+		} else if (Blob.isBlob(submodelElement)) {
+			return Blob.createAsFacade(submodelElement);
+		} else if (File.isFile(submodelElement)) {
+			return File.createAsFacade(submodelElement);
+		} else if (SubmodelElementCollection.isSubmodelElementCollection(submodelElement)) {
+			return SubmodelElementCollection.createAsFacade(submodelElement);
+		} else if (MultiLanguageProperty.isMultiLanguageProperty(submodelElement)) {
+			return MultiLanguageProperty.createAsFacade(submodelElement);
+		} else if (Entity.isEntity(submodelElement)) {
+			return Entity.createAsFacade(submodelElement);
+		} else if (Range.isRange(submodelElement)) {
+			return Range.createAsFacade(submodelElement);
+		} else if (ReferenceElement.isReferenceElement(submodelElement)) {
+			return ReferenceElement.createAsFacade(submodelElement);
+		} else if (RelationshipElement.isRelationshipElement(submodelElement)) {
+			return RelationshipElement.createAsFacade(submodelElement);
+		} else if (AnnotatedRelationshipElement.isAnnotatedRelationshipElement(submodelElement)) {
+			return AnnotatedRelationshipElement.createAsFacade(submodelElement);
+		} else if (Operation.isOperation(submodelElement)) {
+			return Operation.createAsFacade(submodelElement);
+		} else if (BasicEvent.isBasicEvent(submodelElement)) {
+			return BasicEvent.createAsFacade(submodelElement);
+		} else {
+			throw new RuntimeException("Can not create a submodel element from given map: " + submodelElement);
 		}
 	}
+
 	
 }
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/SubModel.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/SubModel.java
deleted file mode 100644
index 93c3f8b..0000000
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/SubModel.java
+++ /dev/null
@@ -1,311 +0,0 @@
-package org.eclipse.basyx.submodel.metamodel.map;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.eclipse.basyx.submodel.metamodel.api.IElementContainer;
-import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
-import org.eclipse.basyx.submodel.metamodel.api.dataspecification.IEmbeddedDataSpecification;
-import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
-import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
-import org.eclipse.basyx.submodel.metamodel.api.qualifier.IAdministrativeInformation;
-import org.eclipse.basyx.submodel.metamodel.api.qualifier.haskind.ModelingKind;
-import org.eclipse.basyx.submodel.metamodel.api.qualifier.qualifiable.IConstraint;
-import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
-import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
-import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
-import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
-import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperation;
-import org.eclipse.basyx.submodel.metamodel.facade.submodelelement.SubmodelElementFacadeFactory;
-import org.eclipse.basyx.submodel.metamodel.map.modeltype.ModelType;
-import org.eclipse.basyx.submodel.metamodel.map.qualifier.AdministrativeInformation;
-import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasDataSpecification;
-import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasSemantics;
-import org.eclipse.basyx.submodel.metamodel.map.qualifier.Identifiable;
-import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangStrings;
-import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
-import org.eclipse.basyx.submodel.metamodel.map.qualifier.haskind.HasKind;
-import org.eclipse.basyx.submodel.metamodel.map.qualifier.qualifiable.Qualifiable;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElement;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation;
-import org.eclipse.basyx.vab.model.VABModelMap;
-
-/**
- * A submodel defines a specific aspect of the asset represented by the AAS.
- * <br />
- * <br />
- * A submodel is used to structure the digital representation and technical
- * functionality of an Administration Shell into distinguishable parts. Each
- * submodel refers to a well-defined domain or subject matter. Submodels can
- * become standardized and thus become submodels types. Submodels can have
- * different life-cycles.
- * 
- * @author kuhn, schnicke
- *
- *
- */
-public class SubModel extends VABModelMap<Object> implements IElementContainer, ISubModel {
-
-	public static final String SUBMODELELEMENT = "submodelElements";
-	public static final String MODELTYPE = "Submodel";
-
-	/**
-	 * Constructor
-	 */
-	public SubModel() {
-		// Add model type
-		putAll(new ModelType(MODELTYPE));
-
-		// Add qualifiers
-		putAll(new HasSemantics());
-		putAll(new Identifiable());
-		putAll(new Qualifiable());
-		putAll(new HasDataSpecification());
-		putAll(new HasKind());
-
-		// Attributes
-		put(SUBMODELELEMENT, new HashMap<String, ISubmodelElement>());
-	}
-
-
-	/**
-	 * Constructor
-	 */
-	public SubModel(HasSemantics semantics, Identifiable identifiable, Qualifiable qualifiable,
-			HasDataSpecification specification, HasKind hasKind) {
-		// Add qualifiers
-		putAll(semantics);
-		putAll(identifiable);
-		putAll(qualifiable);
-		putAll(specification);
-		putAll(hasKind);
-
-		// Attributes
-		put(SUBMODELELEMENT, new HashMap<String, ISubmodelElement>());
-	}
-
-	/**
-	 * Constructor
-	 */
-	public SubModel(List<Property> properties) {
-		this();
-		properties.forEach(this::addSubModelElement);
-	}
-
-	/**
-	 * Constructor
-	 */
-	public SubModel(List<Property> properties, List<Operation> operations) {
-		this();
-		properties.forEach(this::addSubModelElement);
-		operations.forEach(this::addSubModelElement);
-	}
-
-
-	@SuppressWarnings("unchecked")
-	public static SubModel createAsFacade(Map<String, Object> map) {
-		if (map == null) {
-			return null;
-		}
-
-		SubModel ret = new SubModel();
-		
-		Map<String, Object> smElements = new HashMap<>();
-		
-		//SubmodelElemets can be given as Map, Set or List
-		//If it is a Set or List, convert it to a Map first
-		if(map.get(SUBMODELELEMENT) instanceof Collection<?>) {
-			Collection<Object> smElementsSet = (Collection<Object>) map.get(SUBMODELELEMENT);
-			for (Object o: smElementsSet) {
-				Map<String, Object> smElement = (Map<String, Object>) o;
-				String id = (String) smElement.get(Referable.IDSHORT);
-				smElements.put(id, smElement);
-			}
-		} else {
-			smElements = (Map<String, Object>) map.get(SUBMODELELEMENT);
-		}
-		
-		// Transfer map and overwrite SUBMODELELEMENt to prepare it for manual setting
-		ret.setMap(map);
-		ret.put(SUBMODELELEMENT, new HashMap<String, Object>());
-
-		//Iterate through all SubmodelELements and create Facades for them
-		for(Entry<String, Object> smElement: smElements.entrySet()) {
-			ret.getSubmodelElements().put(smElement.getKey(),
-					SubmodelElementFacadeFactory.createSubmodelElement(
-							(Map<String, Object>) smElement.getValue()));
-		}
-
-		return ret;
-	}
-
-	@Override
-	public IReference getSemanticId() {
-		return HasSemantics.createAsFacade(this).getSemanticId();
-	}
-
-	public void setSemanticId(IReference ref) {
-		HasSemantics.createAsFacade(this).setSemanticID(ref);
-	}
-
-	@Override
-	public IAdministrativeInformation getAdministration() {
-		return Identifiable.createAsFacade(this, getKeyElement()).getAdministration();
-	}
-
-	@Override
-	public IIdentifier getIdentification() {
-		return Identifiable.createAsFacade(this, getKeyElement()).getIdentification();
-	}
-
-	public void setAdministration(AdministrativeInformation information) {
-		Identifiable.createAsFacade(this, getKeyElement()).setAdministration(information);
-	}
-
-	public void setIdentification(IdentifierType idType, String id) {
-		Identifiable.createAsFacade(this, getKeyElement()).setIdentification(idType, id);
-	}
-
-	@Override
-	public Collection<IReference> getDataSpecificationReferences() {
-		return HasDataSpecification.createAsFacade(this).getDataSpecificationReferences();
-	}
-
-	public void setDataSpecificationReferences(Collection<IReference> ref) {
-		HasDataSpecification.createAsFacade(this).setDataSpecificationReferences(ref);
-	}
-
-	@Override
-	public Collection<IEmbeddedDataSpecification> getEmbeddedDataSpecifications() {
-		return HasDataSpecification.createAsFacade(this).getEmbeddedDataSpecifications();
-	}
-
-	public void setEmbeddedDataSpecifications(Collection<IEmbeddedDataSpecification> embeddedDataSpecifications) {
-		HasDataSpecification.createAsFacade(this).setEmbeddedDataSpecifications(embeddedDataSpecifications);
-	}
-
-	@Override
-	public ModelingKind getModelingKind() {
-		return HasKind.createAsFacade(this).getModelingKind();
-	}
-
-	public void setModelingKind(ModelingKind kind) {
-		HasKind.createAsFacade(this).setModelingKind(kind);
-	}
-
-	@Override
-	public String getIdShort() {
-		return Referable.createAsFacade(this, getKeyElement()).getIdShort();
-	}
-
-	public void setIdShort(String id) {
-		Referable.createAsFacade(this, getKeyElement()).setIdShort(id);
-	}
-
-	public void setProperties(Map<String, IProperty> properties) {
-		// first, remove all properties
-		Set<Entry<String, ISubmodelElement>> elementSet = getSubmodelElements().entrySet();
-		for ( Iterator<Entry<String, ISubmodelElement>> iterator = elementSet.iterator(); iterator.hasNext(); ) {
-			Entry<String, ISubmodelElement> entry = iterator.next();
-			if (entry.getValue() instanceof IProperty) {
-				iterator.remove();
-			}
-		}
-		// then add all given data properties
-		properties.values().forEach(this::addSubModelElement);
-	}
-
-	public void setOperations(Map<String, IOperation> operations) {
-		// first, remove all operations
-		Set<Entry<String, ISubmodelElement>> elementSet = getSubmodelElements().entrySet();
-		for (Iterator<Entry<String, ISubmodelElement>> iterator = elementSet.iterator(); iterator.hasNext();) {
-			Entry<String, ISubmodelElement> entry = iterator.next();
-			if (entry.getValue() instanceof IOperation) {
-				iterator.remove();
-			}
-		}
-		// then add all given operations
-		operations.values().forEach(this::addSubModelElement);
-	}
-
-	@Override
-	public String getCategory() {
-		return Referable.createAsFacade(this, getKeyElement()).getCategory();
-	}
-
-	@Override
-	public LangStrings getDescription() {
-		return Referable.createAsFacade(this, getKeyElement()).getDescription();
-	}
-
-	@Override
-	public IReference getParent() {
-		return Referable.createAsFacade(this, getKeyElement()).getParent();
-	}
-
-	public void setCategory(String category) {
-		Referable.createAsFacade(this, getKeyElement()).setCategory(category);
-	}
-
-	public void setDescription(LangStrings description) {
-		Referable.createAsFacade(this, getKeyElement()).setDescription(description);
-	}
-
-	public void setParent(IReference obj) {
-		Referable.createAsFacade(this, getKeyElement()).setParent(obj);
-	}
-
-	private KeyElements getKeyElement() {
-		return KeyElements.SUBMODEL;
-	}
-
-	@Override
-	public void addSubModelElement(ISubmodelElement element) {
-		if (element instanceof SubmodelElement) {
-			((SubmodelElement) element).setParent(getReference());
-		}
-		getSubmodelElements().put(element.getIdShort(), element);
-	}
-
-	@Override
-	public Map<String, IProperty> getProperties() {
-		Map<String, IProperty> properties = new HashMap<>();
-		getSubmodelElements().values().forEach(e -> {
-			if (e instanceof IProperty) {
-				properties.put(e.getIdShort(), (IProperty) e);
-			}
-		});
-		return properties;
-	}
-
-	@Override
-	public Map<String, IOperation> getOperations() {
-		Map<String, IOperation> operations = new HashMap<>();
-		getSubmodelElements().values().forEach(e -> {
-			if (e instanceof IOperation) {
-				operations.put(e.getIdShort(), (IOperation) e);
-			}
-		});
-		return operations;
-	}
-	
-	@SuppressWarnings("unchecked")
-	@Override
-	public Map<String, ISubmodelElement> getSubmodelElements() {
-		return (Map<String, ISubmodelElement>) get(SUBMODELELEMENT);
-	}
-	@Override
-	public Collection<IConstraint> getQualifier() {
-		return Qualifiable.createAsFacade(this).getQualifier();
-	}
-
-	@Override
-	public IReference getReference() {
-		return Identifiable.createAsFacade(this, getKeyElement()).getReference();
-	}
-}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/Submodel.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/Submodel.java
new file mode 100644
index 0000000..d3d2374
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/Submodel.java
@@ -0,0 +1,356 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.metamodel.map;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
+import org.eclipse.basyx.submodel.metamodel.api.IElementContainer;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.api.dataspecification.IEmbeddedDataSpecification;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.api.qualifier.IAdministrativeInformation;
+import org.eclipse.basyx.submodel.metamodel.api.qualifier.haskind.ModelingKind;
+import org.eclipse.basyx.submodel.metamodel.api.qualifier.qualifiable.IConstraint;
+import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperation;
+import org.eclipse.basyx.submodel.metamodel.facade.SubmodelElementMapCollectionConverter;
+import org.eclipse.basyx.submodel.metamodel.facade.SubmodelValuesHelper;
+import org.eclipse.basyx.submodel.metamodel.map.helper.ElementContainerHelper;
+import org.eclipse.basyx.submodel.metamodel.map.modeltype.ModelType;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.AdministrativeInformation;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasDataSpecification;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasSemantics;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Identifiable;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangStrings;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.haskind.HasKind;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.qualifiable.Qualifiable;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation;
+import org.eclipse.basyx.vab.model.VABModelMap;
+
+/**
+ * A submodel defines a specific aspect of the asset represented by the AAS.
+ * <br />
+ * <br />
+ * A submodel is used to structure the digital representation and technical
+ * functionality of an Administration Shell into distinguishable parts. Each
+ * submodel refers to a well-defined domain or subject matter. Submodels can
+ * become standardized and thus become submodels types. Submodels can have
+ * different life-cycles.
+ * 
+ * @author kuhn, schnicke
+ *
+ *
+ */
+public class Submodel extends VABModelMap<Object> implements IElementContainer, ISubmodel {
+
+	public static final String SUBMODELELEMENT = "submodelElements";
+	public static final String MODELTYPE = "Submodel";
+
+	/**
+	 * Constructor
+	 */
+	public Submodel() {
+		// Add qualifiers
+		putAll(new Identifiable());
+		putAll(new HasDataSpecification());
+
+		// Add model type
+		putAll(new ModelType(MODELTYPE));
+		setModelingKind(ModelingKind.INSTANCE);
+
+		put(SUBMODELELEMENT, new HashMap<String, ISubmodelElement>());
+
+	}
+	
+	/**
+	 * Constructor accepting only mandatory attribute
+	 * @param idShort
+	 * @param identification
+	 */
+	public Submodel(String idShort, IIdentifier identification) {
+		this();
+		setIdentification(identification);
+		setIdShort(idShort);
+	}
+
+
+	/**
+	 * Constructor
+	 */
+	public Submodel(HasSemantics semantics, Identifiable identifiable, Qualifiable qualifiable,
+			HasDataSpecification specification, HasKind hasKind) {
+		this();
+		// Add qualifiers
+		putAll(semantics);
+		putAll(identifiable);
+		putAll(qualifiable);
+		putAll(specification);
+		putAll(hasKind);
+
+		// Attributes
+		put(SUBMODELELEMENT, new HashMap<String, ISubmodelElement>());
+	}
+
+	/**
+	 * Constructor
+	 */
+	public Submodel(List<Property> properties) {
+		this();
+		properties.forEach(this::addSubmodelElement);
+	}
+
+	/**
+	 * Constructor
+	 */
+	public Submodel(List<Property> properties, List<Operation> operations) {
+		this();
+		properties.forEach(this::addSubmodelElement);
+		operations.forEach(this::addSubmodelElement);
+	}
+
+	public static Submodel createAsFacade(Map<String, Object> map) {
+		if (map == null) {
+			return null;
+		}
+		
+		if (!isValid(map)) {
+			throw new MetamodelConstructionException(Submodel.class, map);
+		}
+		
+		if (!map.containsKey(SUBMODELELEMENT)) {
+			map.put(SUBMODELELEMENT, new ArrayList<>());
+		}
+
+		return SubmodelElementMapCollectionConverter.mapToSM(map);	
+	}
+	
+	/**
+	 * Check whether all mandatory elements for the metamodel
+	 * exist in a map
+	 * @return true/false
+	 */
+	public static boolean isValid(Map<String, Object> map) {
+		return Identifiable.isValid(map);
+	}
+
+	@Override
+	public IReference getSemanticId() {
+		return HasSemantics.createAsFacade(this).getSemanticId();
+	}
+
+	public void setSemanticId(IReference ref) {
+		HasSemantics.createAsFacade(this).setSemanticId(ref);
+	}
+
+	@Override
+	public IAdministrativeInformation getAdministration() {
+		return Identifiable.createAsFacade(this, getKeyElement()).getAdministration();
+	}
+
+	@Override
+	public IIdentifier getIdentification() {
+		return Identifiable.createAsFacade(this, getKeyElement()).getIdentification();
+	}
+
+	public void setAdministration(AdministrativeInformation information) {
+		Identifiable.createAsFacade(this, getKeyElement()).setAdministration(information);
+	}
+
+	public void setIdentification(IIdentifier id) {
+		setIdentification(id.getIdType(), id.getId());
+	}
+
+	public void setIdentification(IdentifierType idType, String id) {
+		Identifiable.createAsFacadeNonStrict(this, getKeyElement()).setIdentification(idType, id);
+	}
+
+	@Override
+	public Collection<IReference> getDataSpecificationReferences() {
+		return HasDataSpecification.createAsFacade(this).getDataSpecificationReferences();
+	}
+
+	public void setDataSpecificationReferences(Collection<IReference> ref) {
+		HasDataSpecification.createAsFacade(this).setDataSpecificationReferences(ref);
+	}
+
+	@Override
+	public Collection<IEmbeddedDataSpecification> getEmbeddedDataSpecifications() {
+		return HasDataSpecification.createAsFacade(this).getEmbeddedDataSpecifications();
+	}
+
+	public void setEmbeddedDataSpecifications(Collection<IEmbeddedDataSpecification> embeddedDataSpecifications) {
+		HasDataSpecification.createAsFacade(this).setEmbeddedDataSpecifications(embeddedDataSpecifications);
+	}
+
+	@Override
+	public ModelingKind getModelingKind() {
+		return HasKind.createAsFacade(this).getModelingKind();
+	}
+
+	public void setModelingKind(ModelingKind kind) {
+		HasKind.createAsFacade(this).setModelingKind(kind);
+	}
+
+	@Override
+	public String getIdShort() {
+		return Referable.createAsFacade(this, getKeyElement()).getIdShort();
+	}
+
+	public void setIdShort(String id) {
+		Referable.createAsFacadeNonStrict(this, getKeyElement()).setIdShort(id);
+	}
+
+	public void setProperties(Map<String, IProperty> properties) {
+		// first, remove all properties
+		Set<Entry<String, ISubmodelElement>> elementSet = getSubmodelElements().entrySet();
+		for ( Iterator<Entry<String, ISubmodelElement>> iterator = elementSet.iterator(); iterator.hasNext(); ) {
+			Entry<String, ISubmodelElement> entry = iterator.next();
+			if (entry.getValue() instanceof IProperty) {
+				iterator.remove();
+			}
+		}
+		// then add all given data properties
+		properties.values().forEach(this::addSubmodelElement);
+	}
+
+	public void setOperations(Map<String, IOperation> operations) {
+		// first, remove all operations
+		Set<Entry<String, ISubmodelElement>> elementSet = getSubmodelElements().entrySet();
+		for (Iterator<Entry<String, ISubmodelElement>> iterator = elementSet.iterator(); iterator.hasNext();) {
+			Entry<String, ISubmodelElement> entry = iterator.next();
+			if (entry.getValue() instanceof IOperation) {
+				iterator.remove();
+			}
+		}
+		// then add all given operations
+		operations.values().forEach(this::addSubmodelElement);
+	}
+
+	@Override
+	public String getCategory() {
+		return Referable.createAsFacade(this, getKeyElement()).getCategory();
+	}
+
+	@Override
+	public LangStrings getDescription() {
+		return Referable.createAsFacade(this, getKeyElement()).getDescription();
+	}
+
+	@Override
+	public IReference getParent() {
+		return Referable.createAsFacade(this, getKeyElement()).getParent();
+	}
+
+	public void setCategory(String category) {
+		Referable.createAsFacade(this, getKeyElement()).setCategory(category);
+	}
+
+	public void setDescription(LangStrings description) {
+		Referable.createAsFacade(this, getKeyElement()).setDescription(description);
+	}
+
+	public void setParent(IReference obj) {
+		Referable.createAsFacade(this, getKeyElement()).setParent(obj);
+	}
+
+	private KeyElements getKeyElement() {
+		return KeyElements.SUBMODEL;
+	}
+
+	@Override
+	public void addSubmodelElement(ISubmodelElement element) {
+		if (element instanceof SubmodelElement) {
+			((SubmodelElement) element).setParent(getReference());
+		}
+		getSubmodelElements().put(element.getIdShort(), element);
+	}
+
+	@Override
+	public Map<String, IProperty> getProperties() {
+		Map<String, IProperty> properties = new HashMap<>();
+		getSubmodelElements().values().forEach(e -> {
+			if (e instanceof IProperty) {
+				properties.put(e.getIdShort(), (IProperty) e);
+			}
+		});
+		return properties;
+	}
+
+	@Override
+	public Map<String, IOperation> getOperations() {
+		Map<String, IOperation> operations = new HashMap<>();
+		getSubmodelElements().values().forEach(e -> {
+			if (e instanceof IOperation) {
+				operations.put(e.getIdShort(), (IOperation) e);
+			}
+		});
+		return operations;
+	}
+	
+	@SuppressWarnings("unchecked")
+	@Override
+	public Map<String, ISubmodelElement> getSubmodelElements() {
+		return (Map<String, ISubmodelElement>) get(SUBMODELELEMENT);
+	}
+
+	@Override
+	public Map<String, Object> getValues() {
+		return SubmodelValuesHelper.getSubmodelValue(this);
+	}
+	
+	@Override
+	public Collection<IConstraint> getQualifiers() {
+		return Qualifiable.createAsFacade(this).getQualifiers();
+	}
+
+	public void setQualifiers(Collection<IConstraint> qualifiers) {
+		Qualifiable.createAsFacade(this).setQualifiers(qualifiers);
+	}
+
+	@Override
+	public IReference getReference() {
+		return Identifiable.createAsFacade(this, getKeyElement()).getReference();
+	}
+
+	/**
+	 * Retrieves an element from element collection
+	 * @param id
+	 * @return retrieved element
+	 */
+	@Override
+	public ISubmodelElement getSubmodelElement(String id) {
+		Map<String, ISubmodelElement> submodelElems = getSubmodelElements();
+		return ElementContainerHelper.getElementById(submodelElems, id);
+	}
+
+	/**
+	 * Deletes an element from element collection
+	 * @param id
+	 */
+	@Override
+	public void deleteSubmodelElement(String id) {
+		Map<String, ISubmodelElement> submodelElems = getSubmodelElements();
+		ElementContainerHelper.removeElementById(submodelElems, id);
+	}
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/dataspecification/DataSpecificationContent.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/dataspecification/DataSpecificationContent.java
index 85de2d0..d1a43b4 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/dataspecification/DataSpecificationContent.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/dataspecification/DataSpecificationContent.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.map.dataspecification;
 
 import java.util.Map;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/dataspecification/DataSpecificationIEC61360.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/dataspecification/DataSpecificationIEC61360.java
index 316aac1..4faeb68 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/dataspecification/DataSpecificationIEC61360.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/dataspecification/DataSpecificationIEC61360.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.map.dataspecification;
 
 import java.util.Map;
@@ -23,8 +32,6 @@
 	 * Creates an empty DataSpecificationIEC61360
 	 */
 	public DataSpecificationIEC61360() {
-		// Add model type
-		put(CONTENT, null);
 		put(DATASPECIFICATION, TEMPLATE_REFERENCE);
 	}
 
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/dataspecification/DataSpecificationIEC61360Content.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/dataspecification/DataSpecificationIEC61360Content.java
index 09121a3..d39e877 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/dataspecification/DataSpecificationIEC61360Content.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/dataspecification/DataSpecificationIEC61360Content.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.map.dataspecification;
 
 import java.util.ArrayList;
@@ -37,22 +46,7 @@
 	/**
 	 * Constructor
 	 */
-	public DataSpecificationIEC61360Content() {
-		// Default values
-		put(PREFERREDNAME, null);
-		put(SHORTNAME, null);
-		put(UNIT, null);
-		put(UNITID, null);
-		put(SOURCEOFDEFINITION, null);
-		put(SYMBOL, null);
-		put(DATATYPE, null);
-		put(DEFINITION, null);
-		put(VALUEFORMAT, null);
-		put(VALUELIST, null);
-		put(VALUE, null);
-		put(VALUEID, null);
-		put(LEVELTYPE, null);
-	}
+	public DataSpecificationIEC61360Content() {}
 
 	/**
 	 * Constructor
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/dataspecification/EmbeddedDataSpecification.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/dataspecification/EmbeddedDataSpecification.java
index 37c31e0..2a0e4a4 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/dataspecification/EmbeddedDataSpecification.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/dataspecification/EmbeddedDataSpecification.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.map.dataspecification;
 
 import java.util.Map;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/dataspecification/ValueReferencePair.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/dataspecification/ValueReferencePair.java
index c34aae7..d73393e 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/dataspecification/ValueReferencePair.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/dataspecification/ValueReferencePair.java
@@ -1,7 +1,17 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.map.dataspecification;
 
 import java.util.Map;
 
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
 import org.eclipse.basyx.submodel.metamodel.api.dataspecification.IValueReferencePair;
 import org.eclipse.basyx.submodel.metamodel.api.qualifier.IIdentifiable;
 import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
@@ -25,10 +35,7 @@
 	/**
 	 * Constructor
 	 */
-	public ValueReferencePair() {
-		setValue(null);
-		setValueId(null);
-	}
+	public ValueReferencePair() {}
 
 	/**
 	 * Constructs a reference based on an {@link IIdentifiable} and additional
@@ -54,11 +61,28 @@
 		if (map == null) {
 			return null;
 		}
-
+		
+		if (!isValid(map)) {
+			throw new MetamodelConstructionException(ValueReferencePair.class, map);
+		}
+		
 		ValueReferencePair ret = new ValueReferencePair();
 		ret.setMap(map);
 		return ret;
 	}
+	
+	/**
+	 * Check whether all mandatory elements for the metamodel
+	 * exist in a map
+	 * @return true/false
+	 */
+	@SuppressWarnings("unchecked")
+	public static boolean isValid(Map<String, Object> map) {
+		return map != null &&
+				map.containsKey(VALUE) && 
+				map.containsKey(VALUEID) &&
+				Reference.isValid((Map<String, Object>)map.get(VALUEID));
+	}
 
 	@Override
 	@SuppressWarnings("unchecked")
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/helper/ElementContainerHelper.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/helper/ElementContainerHelper.java
new file mode 100644
index 0000000..2ce6438
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/helper/ElementContainerHelper.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.metamodel.map.helper;
+
+import java.util.Map;
+
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+
+/**
+ * Contains helper methods of element container
+ * @author haque
+ *
+ */
+public class ElementContainerHelper {
+	
+	public static ISubmodelElement getElementById(Map<String, ISubmodelElement> elements, String id) {
+		if (elements != null && elements.containsKey(id)) {
+			return elements.get(id);
+		}
+		throw new ResourceNotFoundException("Submodel Element with id: " + id + " does not exist");
+	}
+	
+	public static void removeElementById(Map<String, ISubmodelElement> elements, String id) {
+		if (elements != null && elements.containsKey(id)) {
+			elements.remove(id);
+			return;
+		}
+		throw new ResourceNotFoundException("Submodel Element with id: " + id + " does not exist");
+	}
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/identifier/Identifier.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/identifier/Identifier.java
index cbb20b4..7eddd66 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/identifier/Identifier.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/identifier/Identifier.java
@@ -1,7 +1,17 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.map.identifier;
 
 import java.util.Map;
 
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
 import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
 import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
 import org.eclipse.basyx.vab.model.VABModelMap;
@@ -37,11 +47,24 @@
 		if (map == null) {
 			return null;
 		}
-
+		
+		if (!isValid(map)) {
+			throw new MetamodelConstructionException(Identifier.class, map);
+		}
+		
 		Identifier ret = new Identifier();
 		ret.setMap(map);
 		return ret;
 	}
+	
+	/**
+	 * Check whether all mandatory elements for the metamodel
+	 * exist in a map
+	 * @return true/false
+	 */
+	public static boolean isValid(Map<String, Object> map) {
+		return map != null && map.containsKey(IDTYPE) && map.containsKey(ID);
+	}
 
 	/**
 	 * Constructor that accepts parameter
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/modeltype/ModelType.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/modeltype/ModelType.java
index cd77177..d6cf8ed 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/modeltype/ModelType.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/modeltype/ModelType.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.map.modeltype;
 
 import java.util.HashMap;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/parts/ConceptDescription.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/parts/ConceptDescription.java
index 986e30c..a2475e0 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/parts/ConceptDescription.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/parts/ConceptDescription.java
@@ -1,9 +1,19 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.map.parts;
 
 import java.util.Collection;
 import java.util.HashSet;
 import java.util.Map;
 
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
 import org.eclipse.basyx.submodel.metamodel.api.dataspecification.IEmbeddedDataSpecification;
 import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
 import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
@@ -42,6 +52,17 @@
 		// Add attributes
 		put(ISCASEOF, new HashSet<Reference>());
 	}
+	
+	/**
+	 * Constructor accepting only mandatory attribute
+	 * @param idShort
+	 * @param identification
+	 */
+	public ConceptDescription(String idShort, IIdentifier identification) {
+		this();
+		setIdentification(identification.getIdType(), identification.getId());
+		setIdShort(idShort);
+	}
 
 	/**
 	 * Creates a DataSpecificationIEC61360 object from a map
@@ -55,10 +76,23 @@
 		if (map == null) {
 			return null;
 		}
-
+		
+		if (!isValid(map)) {
+			throw new MetamodelConstructionException(ConceptDescription.class, map);
+		}
+		
 		ConceptDescription ret = new ConceptDescription();
 		ret.setMap(map);
-		return ret;
+		return ret;	
+	}
+	
+	/**
+	 * Check whether all mandatory elements for the metamodel
+	 * exist in a map
+	 * @return true/false
+	 */
+	public static boolean isValid(Map<String, Object> map) {
+		return Identifiable.isValid(map);
 	}
 
 	@Override
@@ -94,7 +128,7 @@
 	}
 
 	public void setIdentification(IdentifierType idType, String id) {
-		Identifiable.createAsFacade(this, getKeyElement()).setIdentification(idType, id);
+		Identifiable.createAsFacadeNonStrict(this, getKeyElement()).setIdentification(idType, id);
 	}
 
 	@Override
@@ -126,7 +160,7 @@
 	}
 
 	public void setIdShort(String idShort) {
-		Referable.createAsFacade(this, getKeyElement()).setIdShort(idShort);
+		Referable.createAsFacadeNonStrict(this, getKeyElement()).setIdShort(idShort);
 
 	}
 
@@ -152,4 +186,4 @@
 		return Identifiable.createAsFacade(this, getKeyElement()).getReference();
 	}
 	
-}
\ No newline at end of file
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/AdministrativeInformation.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/AdministrativeInformation.java
index 5235bc7..e654e3e 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/AdministrativeInformation.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/AdministrativeInformation.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.map.qualifier;
 
 import java.util.Collection;
@@ -8,6 +17,8 @@
 import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
 import org.eclipse.basyx.vab.model.VABModelMap;
 
+import com.google.common.base.Strings;
+
 /**
  * AdministrativeInformation class
  * 
@@ -26,9 +37,6 @@
 		// Add qualifier
 		putAll(new HasDataSpecification());
 
-		// Default values
-		put(VERSION, "");
-		put(REVISION, "");
 	}
 
 	/**
@@ -38,9 +46,7 @@
 		// Add qualifier
 		putAll(new HasDataSpecification());
 
-		// Default values
-		put(VERSION, version);
-		put(REVISION, revision);
+		setVersionInformation(version, revision);
 	}
 
 	/**
@@ -78,8 +84,29 @@
 	public void setEmbeddedDataSpecifications(Collection<IEmbeddedDataSpecification> embeddedDataSpecifications) {
 		HasDataSpecification.createAsFacade(this).setEmbeddedDataSpecifications(embeddedDataSpecifications);
 	}
+	
+	/**
+	 * Sets version and revision
+	 * @param version
+	 * @param revision 
+	 * 
+	 * @throws RuntimeException when revision is given without a valid version
+	 */
+	public void setVersionInformation(String version, String revision) {
+		setVersion(version);
+		if (!Strings.isNullOrEmpty(revision)) {
+			if (Strings.isNullOrEmpty(version)) {
+				throw new RuntimeException("revision cannot be set while version is not set");
+			}
+		}
+		setRevision(revision);
+	}
 
-	public void setVersion(String version) {
+	/**
+	 *
+	 * @param version
+	 */
+	private void setVersion(String version) {
 		put(AdministrativeInformation.VERSION, version);
 	}
 
@@ -88,7 +115,11 @@
 		return (String) get(AdministrativeInformation.VERSION);
 	}
 
-	public void setRevision(String revision) {
+	/**
+	 * 
+	 * @param revision
+	 */
+	private void setRevision(String revision) {
 		put(AdministrativeInformation.REVISION, revision);
 	}
 
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/HasDataSpecification.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/HasDataSpecification.java
index 2a29a69..aaa624a 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/HasDataSpecification.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/HasDataSpecification.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.map.qualifier;
 
 import java.util.Collection;
@@ -69,7 +78,7 @@
 	@Override
 	public Collection<IEmbeddedDataSpecification> getEmbeddedDataSpecifications() {
 		Collection<Map<String, Object>> collection = (Collection<Map<String, Object>>) get(EMBEDDEDDATASPECIFICATIONS);
-		return collection.stream().map(EmbeddedDataSpecification::createAsFacade).collect(Collectors.toSet());
+		return collection == null ? new HashSet<IEmbeddedDataSpecification>() : collection.stream().map(EmbeddedDataSpecification::createAsFacade).collect(Collectors.toSet());
 	}
 
 	public void setEmbeddedDataSpecifications(Collection<IEmbeddedDataSpecification> embeddedDataSpecifications) {
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/HasSemantics.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/HasSemantics.java
index 233bd6b..e835cb6 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/HasSemantics.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/HasSemantics.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.map.qualifier;
 
 import java.util.Map;
@@ -19,16 +28,13 @@
 	/**
 	 * Constructor
 	 */
-	public HasSemantics() {
-		// Default values
-		put(SEMANTICID, null);
-	}
+	public HasSemantics() {}
 
 	/**
 	 * Constructor
 	 */
 	public HasSemantics(IReference ref) {
-		this.setSemanticID(ref);
+		this.setSemanticId(ref);
 	}
 
 	/**
@@ -54,7 +60,7 @@
 		return Reference.createAsFacade((Map<String, Object>) get(HasSemantics.SEMANTICID));
 	}
 
-	public void setSemanticID(IReference ref) {
+	public void setSemanticId(IReference ref) {
 		put(HasSemantics.SEMANTICID, ref);
 	}
 }
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/Identifiable.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/Identifiable.java
index d6c6807..e0b8e43 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/Identifiable.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/Identifiable.java
@@ -1,7 +1,17 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.map.qualifier;
 
 import java.util.Map;
 
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
 import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
 import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
 import org.eclipse.basyx.submodel.metamodel.api.qualifier.IAdministrativeInformation;
@@ -27,12 +37,19 @@
 	public Identifiable() {
 		// Add qualifier
 		putAll(new Referable());
-
-		// Administrative information of an element. (AdministrativeInformation)
-		put(ADMINISTRATION, new AdministrativeInformation());
 		// The globally unique identification of an element. (Identificator)
 		put(IDENTIFICATION, new Identifier());
 	}
+	
+	/**
+	 * Constructor with mandatory attribute
+	 * @param idShort
+	 * @param identification
+	 */
+	public Identifiable(String idShort, IIdentifier identification) {
+		super(idShort);
+		setIdentification(identification.getIdType(), identification.getId());
+	}
 
 	/**
 	 * Constructor that accepts values for most relevant properties
@@ -58,7 +75,41 @@
 		if (map == null) {
 			return null;
 		}
-
+		
+		if (!isValid(map)) {
+			throw new MetamodelConstructionException(Identifiable.class, map);
+		}
+		
+		Identifiable ret = new Identifiable();
+		ret.setMap(map);
+		ret.setElementType(type);
+		return ret;
+	}
+	
+	/**
+	 * Check whether all mandatory elements for the metamodel
+	 * exist in a map
+	 * @return true/false
+	 */
+	@SuppressWarnings("unchecked")
+	public static boolean isValid(Map<String, Object> map) {
+		return Referable.isValid(map) &&
+				map.containsKey(Identifiable.IDENTIFICATION) &&
+				Identifier.isValid((Map<String, Object>)map.get(Identifiable.IDENTIFICATION));
+	}
+	
+	/**
+	 * Creates an Identifiable object from a map
+	 * Without checking mandatory attributes present
+	 * @param map
+	 * @param type
+	 * @return
+	 */
+	public static Identifiable createAsFacadeNonStrict(Map<String, Object> map, KeyElements type) {
+		if (map == null) {
+			return null;
+		}
+		
 		Identifiable ret = new Identifiable();
 		ret.setMap(map);
 		ret.setElementType(type);
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/LangString.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/LangString.java
index c22444c..f1f84be 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/LangString.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/LangString.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.map.qualifier;
 
 import java.util.Map;
@@ -12,7 +21,7 @@
  */
 public class LangString extends VABModelMap<Object> {
 	private static final String LANGUAGE = "language";
-	private static final String DESCRIPTION = "description";
+	private static final String DESCRIPTION = "text";
 	
 	private LangString() {
 	}
@@ -44,6 +53,17 @@
 		return ret;
 	}
 	
+	@SuppressWarnings("unchecked")
+	public static boolean isLangString(Object value) {
+		if(!(value instanceof Map<?, ?>)) {
+			return false;
+		}
+		
+		Map<String, Object> map = (Map<String, Object>) value;
+		
+		return map.get(LANGUAGE) instanceof String && map.get(DESCRIPTION) instanceof String;
+	}
+	
 	/**
 	 * Get Language of the langString
 	 * @return Language
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/LangStrings.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/LangStrings.java
index ba12fe6..c3782d1 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/LangStrings.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/LangStrings.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.map.qualifier;
 
 import java.util.Collection;
@@ -65,6 +74,17 @@
 		}
 		return ret;
 	}
+	
+	@SuppressWarnings("unchecked")
+	public static boolean isLangStrings(Object value) {
+		if(!(value instanceof Collection<?>)) {
+			return false;
+		}
+		
+		Collection<Map<String, Object>> collection = (Collection<Map<String, Object>>) value;
+		
+		return collection.stream().allMatch(LangString::isLangString);
+	}
 
 	/**
 	 * 
@@ -92,4 +112,4 @@
 		}
 		return languageSet;
 	}
-}
\ No newline at end of file
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/Referable.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/Referable.java
index 476aa5c..329ad4e 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/Referable.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/Referable.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.map.qualifier;
 
 import java.util.ArrayList;
@@ -5,7 +14,9 @@
 import java.util.List;
 import java.util.Map;
 
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
 import org.eclipse.basyx.submodel.metamodel.api.qualifier.IReferable;
+import org.eclipse.basyx.submodel.metamodel.api.qualifier.IdShortValidator;
 import org.eclipse.basyx.submodel.metamodel.api.reference.IKey;
 import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
 import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
@@ -13,6 +24,8 @@
 import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
 import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
 import org.eclipse.basyx.vab.model.VABModelMap;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * Referable class
@@ -21,6 +34,8 @@
  *
  */
 public class Referable extends VABModelMap<Object> implements IReferable {
+	private static Logger logger = LoggerFactory.getLogger(Referable.class);
+
 	public static final String IDSHORT="idShort";
 	
 	public static final String CATEGORY="category";
@@ -37,16 +52,14 @@
 	public Referable() {
 		// Identifies an element within its name space (String)
 		put(IDSHORT, "");
-		// Coded value that gives further meta information w.r.t. to the type of the
-		// element. It affects the
-		// expected existence of attributes and the applicability of constraints.
-		// (String)
-		put(CATEGORY, "");
-		// Description or comments on the element (String)
-		
-		put(DESCRIPTION, new LangStrings());
-		// Reference to the parent of this element (Referable)
-		put(PARENT, null);
+	}
+	
+	/**
+	 * Constructor with mandatory attribute
+	 * @param idShort
+	 */
+	public Referable(String idShort) {
+		setIdShort(idShort);
 	}
 
 	/**
@@ -68,8 +81,6 @@
 		put(CATEGORY, category);
 		// Description or comments on the element
 		put(DESCRIPTION, description);
-		// Reference to the parent of this element (Referable)
-		put(PARENT, null);
 	}
 
 	/**
@@ -83,12 +94,43 @@
 		if (map == null) {
 			return null;
 		}
-
+		
+		if (!isValid(map)) {
+			throw new MetamodelConstructionException(Referable.class, map);
+		}
 		Referable ret = new Referable();
 		ret.setMap(map);
 		ret.setElementType(type);
 
-		return ret;
+		return ret;	
+	}
+	
+	/**
+	 * Check whether all mandatory elements for the metamodel
+	 * exist in a map
+	 * @return true/false
+	 */
+	public static boolean isValid(Map<String, Object> map) {
+		return map != null && map.get(Referable.IDSHORT) != null;
+	}
+	
+	/**
+	 * Creates a Referable object from a map
+	 * without checking the mandatory attributes present
+	 * @param map
+	 * @param type
+	 * @return
+	 */
+	public static Referable createAsFacadeNonStrict(Map<String, Object> map, KeyElements type) {
+		if (map == null) {
+			return null;
+		}
+		
+		Referable ret = new Referable();
+		ret.setMap(map);
+		ret.setElementType(type);
+
+		return ret;	
 	}
 
 	@Override
@@ -114,6 +156,15 @@
 	}
 
 	public void setIdShort(String idShort) {
+		if(!IdShortValidator.isValid(idShort)) {
+			/*
+			 * Currently, the AASX package explorer does support creating arbitrary
+			 * idShorts. Thus, if this is an exception, AASX files created with the AASX
+			 * package explorer may not be loadable 
+			 * TODO: Replace this with a RuntimeException
+			 */
+			logger.warn("The passed idShort " + idShort + " is not valid! It has to satisfy the RegEx " + IdShortValidator.IDSHORT_REGEX);
+		}
 		put(Referable.IDSHORT, idShort);
 	}
 
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/haskind/HasKind.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/haskind/HasKind.java
index 28946ad..a1c535f 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/haskind/HasKind.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/haskind/HasKind.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.map.qualifier.haskind;
 
 import java.util.Map;
@@ -18,11 +27,7 @@
 	/**
 	 * Constructor
 	 */
-	public HasKind() {
-		// Default value
-
-		put(KIND, null);
-	}
+	public HasKind() {}
 
 	/**
 	 * Constructor that takes
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/qualifiable/Constraint.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/qualifiable/Constraint.java
index ac188a5..c7c78f6 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/qualifiable/Constraint.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/qualifiable/Constraint.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.map.qualifier.qualifiable;
 
 import org.eclipse.basyx.submodel.metamodel.api.qualifier.qualifiable.IConstraint;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/qualifiable/Formula.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/qualifiable/Formula.java
index c676f9a..9865766 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/qualifiable/Formula.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/qualifiable/Formula.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.map.qualifier.qualifiable;
 
 import java.util.Collection;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/qualifiable/Qualifiable.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/qualifiable/Qualifiable.java
index 35da4c2..d3b1c7f 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/qualifiable/Qualifiable.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/qualifiable/Qualifiable.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.map.qualifier.qualifiable;
 
 import java.util.Collection;
@@ -16,16 +25,12 @@
  *
  */
 public class Qualifiable extends VABModelMap<Object> implements IQualifiable {
-	public static final String CONSTRAINTS = "constraints";
+	public static final String QUALIFIERS = "qualifiers";
 
 	/**
 	 * Constructor
 	 */
-	public Qualifiable() {
-		// The instance of an element may be further qualified by one or more
-		// qualifiers.
-		put(CONSTRAINTS, null);
-	}
+	public Qualifiable() {}
 
 	/**
 	 * Constructor
@@ -38,16 +43,16 @@
 
 		// The instance of an element may be further qualified by one or more
 		// qualifiers.
-		put(CONSTRAINTS, qualifiers);
+		put(QUALIFIERS, qualifiers);
 	}
 
 	/**
 	 * Constructor
 	 */
-	public Qualifiable(Collection<Constraint> qualifier) {
+	public Qualifiable(Collection<Constraint> qualifiers) {
 		// The instance of an element may be further qualified by one or more
 		// qualifiers.
-		put(CONSTRAINTS, qualifier);
+		put(QUALIFIERS, qualifiers);
 	}
 
 	/**
@@ -67,15 +72,15 @@
 		return ret;
 	}
 
-	public void setQualifier(Collection<IConstraint> qualifiers) {
-		put(Qualifiable.CONSTRAINTS, qualifiers);
+	public void setQualifiers(Collection<IConstraint> qualifiers) {
+		put(Qualifiable.QUALIFIERS, qualifiers);
 	}
 
 	@SuppressWarnings("unchecked")
 	@Override
-	public Collection<IConstraint> getQualifier() {
+	public Collection<IConstraint> getQualifiers() {
 		// Transform set of maps to set of IConstraints
-		Collection<Map<String, Object>> set = (Collection<Map<String, Object>>) get(Qualifiable.CONSTRAINTS);
+		Collection<Map<String, Object>> set = (Collection<Map<String, Object>>) get(Qualifiable.QUALIFIERS);
 		Collection<IConstraint> ret = new HashSet<>();
 		if (set != null) {
 			for (Map<String, Object> m : set) {
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/qualifiable/Qualifier.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/qualifiable/Qualifier.java
index f5aa959..15d91ac 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/qualifiable/Qualifier.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/qualifiable/Qualifier.java
@@ -1,12 +1,24 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.map.qualifier.qualifiable;
 
 import java.util.Map;
 
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
 import org.eclipse.basyx.submodel.metamodel.api.qualifier.qualifiable.IQualifier;
 import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
 import org.eclipse.basyx.submodel.metamodel.map.modeltype.ModelType;
 import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasSemantics;
 import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueTypeHelper;
 
 /**
  * Qualifier class
@@ -33,24 +45,20 @@
 	public Qualifier() {
 		// Add model type
 		putAll(new ModelType(MODELTYPE));
-
-		// Add all attributes from HasSemantics
-		this.putAll(new HasSemantics());
-
-		// Default values
-		put(TYPE, "");
-		put(VALUE, null);
-		put(VALUEID, null);
-		put(VALUETYPE, "");
+	}
+	
+	/**
+	 * Constructor accepting mandatory attributes
+	 * @param type
+	 * @param valueType
+	 */
+	public Qualifier(String type, String valueType) {
+		this(type, null, valueType, null);
 	}
 
 	public Qualifier(String type, String value, String valueType, Reference valueId) {
-		// Add all attributes from HasSemantics
-		this.putAll(new HasSemantics());
-
-		// Default values
 		put(TYPE,type);
-		put(VALUE, value);
+		put(VALUE, ValueTypeHelper.prepareForSerialization(value));
 		put(VALUEID, valueId);
 		put(VALUETYPE, valueType);
 	}
@@ -66,11 +74,26 @@
 		if (map == null) {
 			return null;
 		}
-
+		
+		if (!isValid(map)) {
+			throw new MetamodelConstructionException(Qualifier.class, map);
+		}
+		
 		Qualifier ret = new Qualifier();
 		ret.setMap(map);
 		return ret;
 	}
+	
+	/**
+	 * Check whether all mandatory elements for the metamodel
+	 * exist in a map
+	 * @return true/false
+	 */
+	public static boolean isValid(Map<String, Object> map) {
+		return map != null &&
+				map.containsKey(TYPE) &&
+				map.containsKey(VALUETYPE);
+	}
 
 	public void setType(String obj) {
 		put(Qualifier.TYPE, obj);
@@ -81,13 +104,22 @@
 		return (String) get(Qualifier.TYPE);
 	}
 
-	public void setValue(String obj) {
-		put(Qualifier.VALUE, obj);
+	public void setValue(Object obj) {
+		put(Qualifier.VALUE, ValueTypeHelper.prepareForSerialization(obj));
+		// Value type is only set if it is not set before
+		if(getValueType() == null) {
+			put(Qualifier.VALUETYPE, ValueTypeHelper.getType(obj).toString());
+		}
 	}
 
 	@Override
-	public String getValue() {
-		return (String) get(Qualifier.VALUE);
+	public Object getValue() {
+		Object value = get(Qualifier.VALUE);
+		if(value instanceof String) {
+			return ValueTypeHelper.getJavaObject(value, getValueType());
+		}else {
+			return value;
+		}
 	}
 
 	public void setValueId(IReference obj) {
@@ -100,13 +132,13 @@
 		return Reference.createAsFacade((Map<String, Object>) get(Qualifier.VALUEID));
 	}
 
-	public void setValueType(String obj) {
-		put(Qualifier.VALUETYPE, obj);
+	public void setValueType(ValueType obj) {
+		put(Qualifier.VALUETYPE, obj.toString());
 	}
 	
 	@Override
-	public String getValueType() {
-		return (String) get(Qualifier.VALUETYPE);
+	public ValueType getValueType() {
+		return ValueTypeHelper.readTypeDef(get(Qualifier.VALUETYPE));
 	}
 
 	@Override
@@ -114,7 +146,7 @@
 		return HasSemantics.createAsFacade(this).getSemanticId();
 	}
 
-	public void setSemanticID(IReference ref) {
-		HasSemantics.createAsFacade(this).setSemanticID(ref);
+	public void setSemanticId(IReference ref) {
+		HasSemantics.createAsFacade(this).setSemanticId(ref);
 	}
 }
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/reference/Key.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/reference/Key.java
index d6dc50d..9424e61 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/reference/Key.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/reference/Key.java
@@ -1,7 +1,17 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.map.reference;
 
 import java.util.Map;
 
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
 import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
 import org.eclipse.basyx.submodel.metamodel.api.reference.IKey;
 import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
@@ -74,11 +84,53 @@
 		if (map == null) {
 			return null;
 		}
-
+		
+		if (!isValid(map)) {
+			throw new MetamodelConstructionException(Key.class, map);
+		}
+		
 		Key ret = new Key();
 		ret.setMap(map);
 		return ret;
 	}
+	
+	/**
+	 * Check whether all mandatory elements for the metamodel
+	 * exist in a map
+	 * @return true/false
+	 */
+	public static boolean isValid(Map<String, Object> map) {
+		return map != null &&
+				map.containsKey(TYPE) &&
+				map.containsKey(LOCAL) &&
+				map.containsKey(VALUE) &&
+				map.containsKey(IDTYPE);
+	}
+	
+	@SuppressWarnings("unchecked")
+	public static boolean isKey(Object value) {
+		if(!(value instanceof Map<?, ?>)) {
+			return false;
+		}
+		
+		Map<String, Object> map = (Map<String, Object>) value;
+		
+		if(!(map.get(LOCAL) instanceof Boolean && map.get(VALUE) instanceof String
+				&& map.get(IDTYPE) instanceof String && map.get(TYPE) instanceof String)) {
+			return false;
+		}
+		
+		try {
+			// Try to convert the Strings to Enum-Types
+			// If that fails an Exception is thrown
+			KeyType.fromString((String) map.get(IDTYPE));
+			KeyElements.fromString((String) map.get(TYPE));
+		} catch (IllegalArgumentException e) {
+			return false;
+		}
+		
+		return true;
+	}
 
 	@Override
 	public KeyElements getType() {
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/reference/Reference.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/reference/Reference.java
index d7f7717..23502c0 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/reference/Reference.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/reference/Reference.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.map.reference;
 
 import java.util.ArrayList;
@@ -6,6 +15,7 @@
 import java.util.List;
 import java.util.Map;
 
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
 import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
 import org.eclipse.basyx.submodel.metamodel.api.qualifier.IIdentifiable;
 import org.eclipse.basyx.submodel.metamodel.api.reference.IKey;
@@ -87,11 +97,67 @@
 		if (map == null) {
 			return null;
 		}
-
+		
+		if (!isValid(map)) {
+			throw new MetamodelConstructionException(Reference.class, map);
+		}
+		
 		Reference ret = new Reference();
 		ret.setMap(map);
 		return ret;
 	}
+	
+	/**
+	 * Check whether all mandatory elements for the metamodel
+	 * exist in a map
+	 * @return true/false
+	 */
+	@SuppressWarnings("unchecked")
+	public static boolean isValid(Map<String, Object> map) {
+		if (map != null && map.containsKey(Reference.KEY)) {
+			Collection<Map<String, Object>> keysCollection = (Collection<Map<String, Object>>)map.get(Reference.KEY);
+			for (Map<String, Object> key : keysCollection) {
+				if (!Key.isValid(key)) {
+					return false;
+				}
+			}
+			return true;
+		}
+		return false;
+	}
+	
+	/**
+	 * Creates a Reference object from a map
+	 * without checking mandatory attributes present
+	 * 
+	 * @param obj
+	 *            a Reference object as raw map
+	 * @return a Reference object, that behaves like a facade for the given map
+	 */
+	public static Reference createAsFacadeNonStrict(Map<String, Object> map) {
+		if (map == null) {
+			return null;
+		}
+		
+		Reference ret = new Reference();
+		ret.setMap(map);
+		return ret;
+	}
+	
+	@SuppressWarnings("unchecked")
+	public static boolean isReference(Object value) {
+		if(!(value instanceof Map<?, ?>)) {
+			return false;
+		}
+		
+		Map<String, Object> map = (Map<String, Object>) value;
+		
+		if(!(map.get(KEY) instanceof Collection<?>)) {
+			return false;
+		}
+		
+		return ((Collection<Key>) map.get(KEY)).stream().allMatch(Key::isKey);
+	}
 
 	@SuppressWarnings("unchecked")
 	@Override
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/reference/ReferenceHelper.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/reference/ReferenceHelper.java
index 8be4399..de82c04 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/reference/ReferenceHelper.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/reference/ReferenceHelper.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.map.reference;
 
 import java.util.Collection;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/SubmodelElement.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/SubmodelElement.java
index f1a81bb..6d151ae 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/SubmodelElement.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/SubmodelElement.java
@@ -1,14 +1,25 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.map.submodelelement;
 
 import java.util.Collection;
 import java.util.Map;
 
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
 import org.eclipse.basyx.submodel.metamodel.api.dataspecification.IEmbeddedDataSpecification;
 import org.eclipse.basyx.submodel.metamodel.api.qualifier.haskind.ModelingKind;
 import org.eclipse.basyx.submodel.metamodel.api.qualifier.qualifiable.IConstraint;
 import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
 import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
 import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.SubmodelElementIdShortBlacklist;
 import org.eclipse.basyx.submodel.metamodel.map.modeltype.ModelType;
 import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasDataSpecification;
 import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasSemantics;
@@ -31,12 +42,16 @@
 	protected SubmodelElement() {
 		// Add model type
 		putAll(new ModelType(MODELTYPE));
+		setModelingKind(ModelingKind.INSTANCE);
+	}
 
-		putAll(new HasDataSpecification());
-		putAll(new Referable());
-		putAll(new Qualifiable());
-		putAll(new HasSemantics());
-		putAll(new HasKind());
+	/**
+	 * Constructor with only mandatory attribute
+	 * @param idShort
+	 */
+	protected SubmodelElement(String idShort) {
+		this();
+		setIdShort(idShort);
 	}
 	
 	/**
@@ -46,10 +61,27 @@
 	 * @return a SubmodelElement object, that behaves like a facade for the given map
 	 */
 	public static SubmodelElement createAsFacade(Map<String, Object> obj) {
+		if (obj == null) {
+			return null;
+		}
+		
+		if (!isValid(obj)) {
+			throw new MetamodelConstructionException(SubmodelElement.class, obj);	
+		}
+
 		SubmodelElement ret = new SubmodelElement();
 		ret.setMap(obj);
 		return ret;
 	}
+	
+	/**
+	 * Check whether all mandatory elements for the metamodel
+	 * exist in a map
+	 * @return true/false
+	 */
+	public static boolean isValid(Map<String, Object> obj) {
+		return Referable.isValid(obj);
+	}
 
 	@Override
 	public Collection<IReference> getDataSpecificationReferences() {
@@ -94,7 +126,11 @@
 	}
 
 	public void setIdShort(String idShort) {
-		Referable.createAsFacade(this, getKeyElement()).setIdShort(idShort);
+		if (SubmodelElementIdShortBlacklist.isBlacklisted(idShort)) {
+			throw new RuntimeException("The passed idShort " + idShort + " is blacklisted.");
+		}
+
+		Referable.createAsFacadeNonStrict(this, getKeyElement()).setIdShort(idShort);
 	}
 
 	public void setCategory(String category) {
@@ -109,13 +145,13 @@
 		Referable.createAsFacade(this, getKeyElement()).setParent(obj);
 	}
 
-	public void setQualifier(Collection<IConstraint> qualifiers) {
-		Qualifiable.createAsFacade(this).setQualifier(qualifiers);
+	public void setQualifiers(Collection<IConstraint> qualifiers) {
+		Qualifiable.createAsFacade(this).setQualifiers(qualifiers);
 	}
 
 	@Override
-	public Collection<IConstraint> getQualifier() {
-		return Qualifiable.createAsFacade(this).getQualifier();
+	public Collection<IConstraint> getQualifiers() {
+		return Qualifiable.createAsFacade(this).getQualifiers();
 	}
 
 	@Override
@@ -123,8 +159,8 @@
 		return HasSemantics.createAsFacade(this).getSemanticId();
 	}
 
-	public void setSemanticID(IReference ref) {
-		HasSemantics.createAsFacade(this).setSemanticID(ref);
+	public void setSemanticId(IReference ref) {
+		HasSemantics.createAsFacade(this).setSemanticId(ref);
 	}
 
 	@Override
@@ -146,4 +182,21 @@
 	public IReference getReference() {
 		return Referable.createAsFacade(this, getKeyElement()).getReference();
 	}
+	
+	@Override
+	public Object getValue() {
+		throw new UnsupportedOperationException("getValue is only possible in specific Element");
+	}
+	
+	@Override
+	public void setValue(Object value) {
+		throw new UnsupportedOperationException("setValue is only possible in specific Element");
+	}
+
+	public SubmodelElement getLocalCopy() {
+		// Return a shallow copy
+		SubmodelElement copy = new SubmodelElement();
+		copy.putAll(this);
+		return copy;
+	}
 }
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/SubmodelElementCollection.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/SubmodelElementCollection.java
index 4047e14..df8a35b 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/SubmodelElementCollection.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/SubmodelElementCollection.java
@@ -1,18 +1,30 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.map.submodelelement;
 
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.HashMap;
-import java.util.List;
 import java.util.Map;
 
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
+import org.eclipse.basyx.submodel.metamodel.api.IElementContainer;
 import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
 import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
 import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
 import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElementCollection;
 import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
 import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperation;
-import org.eclipse.basyx.submodel.metamodel.facade.submodelelement.SubmodelElementFacadeFactory;
+import org.eclipse.basyx.submodel.metamodel.facade.SubmodelElementMapCollectionConverter;
+import org.eclipse.basyx.submodel.metamodel.map.helper.ElementContainerHelper;
 import org.eclipse.basyx.submodel.metamodel.map.modeltype.ModelType;
 import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasDataSpecification;
 import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangStrings;
@@ -27,7 +39,7 @@
  * @author schnicke
  *
  */
-public class SubmodelElementCollection extends SubmodelElement implements ISubmodelElementCollection {
+public class SubmodelElementCollection extends SubmodelElement implements ISubmodelElementCollection, IElementContainer {
 	public static final String ORDERED = "ordered";
 	public static final String ALLOWDUPLICATES = "allowDuplicates";
 	public static final String MODELTYPE = "SubmodelElementCollection";
@@ -41,10 +53,25 @@
 		putAll(new ModelType(MODELTYPE));
 
 		// Put attributes
-		put(Property.VALUE, new ArrayList<>());
+		put(Property.VALUE, new HashMap<>());
 		put(ORDERED, true);
 		put(ALLOWDUPLICATES, true);
 	}
+	
+	/**
+	 * Constructor with only mandatory attribute
+	 * @param idShort
+	 */
+	public SubmodelElementCollection(String idShort) {
+		super(idShort);
+		// Add model type
+		putAll(new ModelType(MODELTYPE));
+
+		// Put attributes
+		setValue(new ArrayList<>());
+		setOrdered(true);
+		setAllowDuplicates(true);
+	}
 
 	/**
 	 * 
@@ -63,7 +90,7 @@
 		putAll(new ModelType(MODELTYPE));
 		
 		// Put attributes
-		put(Property.VALUE, value);
+		put(Property.VALUE, SubmodelElementMapCollectionConverter.convertCollectionToIDMap(value));
 		put(ORDERED, ordered);
 		put(ALLOWDUPLICATES, allowDuplicates);
 	}
@@ -75,9 +102,24 @@
 	 * @return a SubmodelElementCollection object, that behaves like a facade for the given map
 	 */
 	public static SubmodelElementCollection createAsFacade(Map<String, Object> obj) {
-		SubmodelElementCollection ret = new SubmodelElementCollection();
-		ret.setMap(obj);
-		return ret;
+		if (obj == null) {
+			return null;
+		}
+		
+		if (!isValid(obj)) {
+			throw new MetamodelConstructionException(SubmodelElementCollection.class, obj);
+		}
+		
+		return SubmodelElementMapCollectionConverter.mapToSmECollection(obj);
+	}
+	
+	/**
+	 * Check whether all mandatory elements for the metamodel
+	 * exist in a map
+	 * @return true/false
+	 */
+	public static boolean isValid(Map<String, Object> obj) {
+		return SubmodelElement.isValid(obj);
 	}
 	
 	/**
@@ -86,8 +128,8 @@
 	public static boolean isSubmodelElementCollection(Map<String, Object> map) {
 		String modelType = ModelType.createAsFacade(map).getName();
 		// Either model type is set or the element type specific attributes are contained (fallback)
-		return MODELTYPE.equals(modelType)
-				|| (map.containsKey(Property.VALUE) && map.containsKey(ORDERED) && map.containsKey(ALLOWDUPLICATES));
+		return MODELTYPE.equals(modelType) || (modelType == null
+				&& (map.containsKey(Property.VALUE) && map.containsKey(ORDERED) && map.containsKey(ALLOWDUPLICATES)));
 	}
 
 	/**
@@ -96,11 +138,12 @@
 	 * @param elem
 	 */
 	@SuppressWarnings("unchecked")
-	public void addElement(ISubmodelElement elem) {
+	@Override
+	public void addSubmodelElement(ISubmodelElement elem) {
 		if (elem instanceof SubmodelElement) {
 			((SubmodelElement) elem).setParent(getReference());
 		}
-		((List<Object>) get(Property.VALUE)).add(elem);
+		((Map<String, ISubmodelElement>) get(Property.VALUE)).put(elem.getIdShort(), elem);
 	}
 
 	@Override
@@ -129,20 +172,14 @@
 		return Referable.createAsFacade(this, getKeyElement()).getDescription();
 	}
 
-	public void setValue(Collection<ISubmodelElement> value) {
-		put(Property.VALUE, value);
+	@Override
+	public void setValue(Object value) {
+		put(Property.VALUE, SubmodelElementMapCollectionConverter.convertCollectionToIDMap(value));
 	}
 
 	@Override
-	@SuppressWarnings("unchecked")
 	public Collection<ISubmodelElement> getValue() {
-		Collection<ISubmodelElement> ret = new ArrayList<>();
-		Collection<Object> smElems = (ArrayList<Object>) get(Property.VALUE);
-		for(Object smElemO: smElems) {
-			Map<String, Object> smElem = (Map<String, Object>) smElemO;
-			ret.add(SubmodelElementFacadeFactory.createSubmodelElement(smElem));
-		}
-		return ret;
+		return Collections.unmodifiableList(new ArrayList<>((getSubmodelElements()).values()));
 	}
 
 	public void setOrdered(boolean value) {
@@ -164,38 +201,31 @@
 	}
 
 	public void setElements(Map<String, ISubmodelElement> value) {
-		put(Property.VALUE, value.values());
-	}
-
-	public void setElements(Collection<ISubmodelElement> value) {
 		put(Property.VALUE, value);
 	}
 
-	@Override
+	public void setElements(Collection<ISubmodelElement> value) {
+		put(Property.VALUE, SubmodelElementMapCollectionConverter.convertCollectionToIDMap(value));
+	}
+
 	@SuppressWarnings("unchecked")
+	@Override
 	public Map<String, ISubmodelElement> getSubmodelElements() {
-		Map<String, ISubmodelElement> ret = new HashMap<>();
-		Collection<Object> smElems = (Collection<Object>) get(Property.VALUE);
-		for(Object smElemO: smElems) {
-			Map<String, Object> smElem = (Map<String, Object>) smElemO;
-			ret.put((String) smElem.get(Referable.IDSHORT), SubmodelElementFacadeFactory.createSubmodelElement(smElem));
-		}
-		return ret;
+		return (Map<String, ISubmodelElement>) get(Property.VALUE);
 	}
 
 	@SuppressWarnings("unchecked")
 	@Override
 	public Map<String, IProperty> getProperties() {
 		Map<String, IProperty> ret = new HashMap<>();
-		Collection<Object> smElems = (Collection<Object>) get(Property.VALUE);
-		for (Object smElemO : smElems) {
-			Map<String, Object> smElem = (Map<String, Object>) smElemO;
-			if (Property.isProperty(smElem)) {
-				String idShort = Referable.createAsFacade(smElem, KeyElements.DATAELEMENT).getIdShort();
-				IProperty dataElement = (IProperty) SubmodelElementFacadeFactory.createSubmodelElement(smElem);
-				ret.put(idShort, dataElement);
+		Map<String, ISubmodelElement> smElems = (Map<String, ISubmodelElement>) get(Property.VALUE);
+		
+		for(ISubmodelElement smElement: smElems.values()) {
+			if (Property.isProperty((Map<String, Object>) smElement)) {
+				ret.put(smElement.getIdShort(), (IProperty) smElement);
 			}
 		}
+
 		return ret;
 	}
 
@@ -203,19 +233,56 @@
 	@Override
 	public Map<String, IOperation> getOperations() {
 		Map<String, IOperation> ret = new HashMap<>();
-		Collection<Object> smElems = (Collection<Object>) get(Property.VALUE);
-		for (Object smElemO : smElems) {
-			Map<String, Object> smElem = (Map<String, Object>) smElemO;
-			if (Operation.isOperation(smElem)) {
-				String idShort = Referable.createAsFacade(smElem, KeyElements.OPERATION).getIdShort();
-				ret.put(idShort, Operation.createAsFacade(smElem));
+		Map<String, ISubmodelElement> smElems = (Map<String, ISubmodelElement>) get(Property.VALUE);
+		
+		for(ISubmodelElement smElement: smElems.values()) {
+			if (Operation.isOperation(smElement)) {
+				ret.put(smElement.getIdShort(), (IOperation) smElement);
 			}
 		}
+
 		return ret;
 	}
+
+	/**
+	 * Retrieves an element from element collection
+	 * @param id
+	 * @return retrieved element
+	 */
+	@SuppressWarnings("unchecked")
+	@Override
+	public ISubmodelElement getSubmodelElement(String id) {
+		Map<String, ISubmodelElement> submodelElems = (Map<String, ISubmodelElement>) get(Property.VALUE);
+		return ElementContainerHelper.getElementById(submodelElems, id);
+	}
+
+	/**
+	 * Deletes an element from element collection
+	 * @param id
+	 */
+	@SuppressWarnings("unchecked")
+	@Override
+	public void deleteSubmodelElement(String id) {
+		Map<String, ISubmodelElement> submodelElems = (Map<String, ISubmodelElement>) get(Property.VALUE);
+		ElementContainerHelper.removeElementById(submodelElems, id);
+	}
 	
 	@Override
 	protected KeyElements getKeyElement() {
 		return KeyElements.SUBMODELELEMENTCOLLECTION;
 	}
+
+	@Override
+	public SubmodelElementCollection getLocalCopy() {
+		// Create a shallow copy
+		SubmodelElementCollection copy = new SubmodelElementCollection();
+		copy.putAll(this);
+		// Then clone all submodelElements
+		Collection<ISubmodelElement> value = getValue();
+		Collection<ISubmodelElement> clonedValue = new ArrayList<>();
+		value.forEach(element -> clonedValue.add(element.getLocalCopy()));
+		// And return this copy with the cloned values
+		copy.setValue(clonedValue);
+		return copy;
+	}
 }
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/Blob.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/Blob.java
index ef72c24..2926c82 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/Blob.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/Blob.java
@@ -1,7 +1,19 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement;
 
+import java.nio.charset.StandardCharsets;
+import java.util.Base64;
 import java.util.Map;
 
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
 import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
 import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IBlob;
 import org.eclipse.basyx.submodel.metamodel.map.modeltype.ModelType;
@@ -14,8 +26,8 @@
  *
  */
 public class Blob extends DataElement implements IBlob {
-	public static final String MIMETYPE="mimeType";
-	public static final String MODELTYPE = "blob";
+	public static final String MIMETYPE = "mimeType";
+	public static final String MODELTYPE = "Blob";
 	
 	/**
 	 * Creates an empty Blob object
@@ -24,6 +36,17 @@
 		// Add model type
 		putAll(new ModelType(MODELTYPE));
 	}
+	
+	/**
+	 * Constructor accepting only mandatory attribute
+	 * @param idShort
+	 * @param mimeType
+	 */
+	public Blob(String idShort, String mimeType) {
+		super(idShort);
+		putAll(new ModelType(MODELTYPE));
+		setMimeType(mimeType);
+	}
 
 	/**
 	 * Has to have a MimeType
@@ -38,7 +61,7 @@
 		// Add model type
 		putAll(new ModelType(MODELTYPE));
 
-		setValue(value);
+		setByteArrayValue(value);
 		setMimeType(mimeType);
 	}
 	
@@ -49,12 +72,29 @@
 	 * @return a Blob object, that behaves like a facade for the given map
 	 */
 	public static Blob createAsFacade(Map<String, Object> obj) {
+		if (obj == null) {
+			return null;
+		}
+		
+		if (!isValid(obj)) {
+			throw new MetamodelConstructionException(Blob.class, obj);
+		}
+		
 		Blob facade = new Blob();
 		facade.setMap(obj);
 		return facade;
 	}
 	
 	/**
+	 * Check whether all mandatory elements for the metamodel
+	 * exist in a map
+	 * @return true/false
+	 */
+	public static boolean isValid(Map<String, Object> obj) {
+		return DataElement.isValid(obj) && obj.containsKey(Blob.MIMETYPE);
+	}
+	
+	/**
 	 * Returns true if the given submodel element map is recognized as a blob
 	 */
 	public static boolean isBlob(Map<String, Object> map) {
@@ -62,22 +102,51 @@
 		// Either model type is set or the element type specific attributes are contained (fallback)
 		// Note: Fallback is ambiguous - File has exactly the same attributes
 		// => would need value parsing in order to be able to differentiate
-		return MODELTYPE.equals(modelType) || (map.containsKey(Property.VALUE) && map.containsKey(MIMETYPE));
-	}
-
-	public void setValue(byte[] value) {
-		put(Property.VALUE, new String(value));
-		
+		return MODELTYPE.equals(modelType)
+				|| (modelType == null && (map.containsKey(Property.VALUE) && map.containsKey(MIMETYPE)));
 	}
 
 	@Override
-	public byte[] getValue() {
-		return ((String) get(Property.VALUE)).getBytes();
+	public void setValue(Object value) {
+		if (value instanceof String) {
+			// Assume a Base64 encoded String
+			setValue((String) value);
+		} else {
+			throw new IllegalArgumentException("Given Object is not a String");
+		}
+	}
+
+	@Override
+	public String getValue() {
+		if (!containsKey(Property.VALUE)) {
+			return null;
+		}
+		return (String) get(Property.VALUE);
+	}
+	
+	@Override
+	public byte[] getByteArrayValue() {
+		String value = getValue();
+		if ( value != null ) {
+			return Base64.getDecoder().decode(value);
+		} else {
+			return null;
+		}
+	}
+
+	@Override
+	public String getUTF8String() {
+		byte[] value = getByteArrayValue();
+		return new String(value, StandardCharsets.UTF_8);
+	}
+
+	@Override
+	public void setUTF8String(String text) {
+		setByteArrayValue(text.getBytes(StandardCharsets.UTF_8));
 	}
 
 	public void setMimeType(String mimeType) {
 		put(Blob.MIMETYPE, mimeType);
-		
 	}
 
 	@Override
@@ -89,4 +158,26 @@
 	protected KeyElements getKeyElement() {
 		return KeyElements.BLOB;
 	}
+
+	@Override
+	public Blob getLocalCopy() {
+		// Return a shallow copy
+		Blob copy = new Blob();
+		copy.putAll(this);
+		return copy;
+	}
+
+	@Override
+	public void setByteArrayValue(byte[] value) {
+		if (value != null) {
+			setValue(Base64.getEncoder().encodeToString(value));
+		} else {
+			setValue(null);
+		}
+	}
+
+	@Override
+	public void setValue(String value) {
+		put(Property.VALUE, value);
+	}
 }
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/DataElement.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/DataElement.java
index 7c72dc1..e939a82 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/DataElement.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/DataElement.java
@@ -1,12 +1,23 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement;
 
 import java.util.Map;
 
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
 import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
 import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IDataElement;
 import org.eclipse.basyx.submodel.metamodel.map.modeltype.ModelType;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElement;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.range.Range;
 
 public class DataElement extends SubmodelElement implements IDataElement {
 	public static final String MODELTYPE = "DataElement";
@@ -15,8 +26,48 @@
 		// Add model type
 		putAll(new ModelType(MODELTYPE));
 	}
+	
+	/**
+	 * Constructor with mandatory attribute
+	 * @param idShort
+	 */
+	public DataElement(String idShort) {
+		super(idShort);
+		
+		// Add model type
+		putAll(new ModelType(MODELTYPE));
+	}
 
 	/**
+	 * Creates a DataElement object from a map
+	 * 
+	 * @param obj a DataElement object as raw map
+	 * @return a DataElement object, that behaves like a facade for the given map
+	 */
+	public static DataElement createAsFacade(Map<String, Object> obj) {
+		if (obj == null) {
+			return null;
+		}
+		
+		if (!isValid(obj)) {
+			throw new MetamodelConstructionException(DataElement.class, obj);
+		}
+		
+		DataElement facade = new DataElement();
+		facade.setMap(obj);
+		return facade;
+	}
+	
+	/**
+	 * Check whether all mandatory elements for the metamodel
+	 * exist in a map
+	 * @return true/false
+	 */
+	public static boolean isValid(Map<String, Object> obj) {
+		return SubmodelElement.isValid(obj);
+	}
+	
+	/**
 	 * Returns true if the given submodel element map is recognized as a data element
 	 */
 	public static boolean isDataElement(Map<String, Object> map) {
@@ -30,4 +81,12 @@
 	protected KeyElements getKeyElement() {
 		return KeyElements.DATAELEMENT;
 	}
+
+	@Override
+	public DataElement getLocalCopy() {
+		// Return a shallow copy
+		DataElement copy = new DataElement();
+		copy.putAll(this);
+		return copy;
+	}
 }
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/File.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/File.java
index da90b35..8ebde4f 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/File.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/File.java
@@ -1,7 +1,17 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement;
 
 import java.util.Map;
 
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
 import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
 import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IFile;
 import org.eclipse.basyx.submodel.metamodel.map.modeltype.ModelType;
@@ -26,6 +36,15 @@
 	}
 	
 	/**
+	 * Constructor accepting only mandatory attribute
+	 * @param mimeType
+	 */
+	public File(String mimeType) {
+		this();
+		setMimeType(mimeType);
+	}
+	
+	/**
 	 * Creates a file data element. It has to have a mimeType <br/>
 	 * An absolute path is used in the case that the file exists independently of
 	 * the AAS. A relative path, relative to the package root should be used if the
@@ -54,10 +73,27 @@
 	 * @return a File object, that behaves like a facade for the given map
 	 */
 	public static File createAsFacade(Map<String, Object> obj) {
+		if (obj == null) {
+			return null;
+		}
+		
+		if (!isValid(obj)) {
+			throw new MetamodelConstructionException(File.class, obj);
+		}
+		
 		File facade = new File();
 		facade.setMap(obj);
 		return facade;
 	}
+	
+	/**
+	 * Check whether all mandatory elements for the metamodel
+	 * exist in a map
+	 * @return true/false
+	 */
+	public static boolean isValid(Map<String, Object> obj) {
+		return DataElement.isValid(obj) && obj.containsKey(File.MIMETYPE);
+	}
 
 	/**
 	 * Returns true if the given submodel element map is recognized as a fiel
@@ -67,11 +103,19 @@
 		// Either model type is set or the element type specific attributes are contained (fallback)
 		// Note: Fallback is ambiguous - Blob has exactly the same attributes
 		// => would need value parsing in order to be able to differentiate
-		return MODELTYPE.equals(modelType) || (map.containsKey(Property.VALUE) && map.containsKey(MIMETYPE));
+		return MODELTYPE.equals(modelType)
+				|| (modelType == null && (map.containsKey(Property.VALUE) && map.containsKey(MIMETYPE)));
 	}
 
-	public void setValue(String value) {
-		put(Property.VALUE, value);
+	@Override
+	public void setValue(Object value) {
+		if(value instanceof String) {
+			setValue((String) value);
+		}
+		else {
+			throw new IllegalArgumentException("Given Object is not a String");
+		}
+		
 	}
 
 	@Override
@@ -92,4 +136,17 @@
 	protected KeyElements getKeyElement() {
 		return KeyElements.FILE;
 	}
+
+	@Override
+	public File getLocalCopy() {
+		// Return a shallow copy
+		File copy = new File();
+		copy.putAll(this);
+		return copy;
+	}
+
+	@Override
+	public void setValue(String value) {
+		put(Property.VALUE, value);
+	}
 }
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/MultiLanguageProperty.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/MultiLanguageProperty.java
index 5510004..daa9ca2 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/MultiLanguageProperty.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/MultiLanguageProperty.java
@@ -1,8 +1,18 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement;
 
 import java.util.Collection;
 import java.util.Map;
 
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
 import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
 import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
 import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IMultiLanguageProperty;
@@ -28,6 +38,16 @@
 		putAll(new ModelType(MODELTYPE));
 	}
 	
+	/**
+	 * Constructor accepting only mandatory attribute
+	 * @param idShort
+	 */
+	public MultiLanguageProperty(String idShort) {
+		super(idShort);
+		// Add model type
+		putAll(new ModelType(MODELTYPE));
+	}
+	
 	public MultiLanguageProperty(Reference reference, LangStrings langStrings) {
 		this();
 		put(VALUE, langStrings);
@@ -41,20 +61,37 @@
 	 * @return a MultiLanguageProperty object, that behaves like a facade for the given map
 	 */
 	public static MultiLanguageProperty createAsFacade(Map<String, Object> obj) {
+		if (obj == null) {
+			return null;
+		}
+		
+		if (!isValid(obj)) {
+			throw new MetamodelConstructionException(MultiLanguageProperty.class, obj);
+		}
+		
 		MultiLanguageProperty facade = new MultiLanguageProperty();
 		facade.setMap(obj);
 		return facade;
 	}
 	
 	/**
+	 * Check whether all mandatory elements for the metamodel
+	 * exist in a map
+	 * @return true/false
+	 */
+	public static boolean isValid(Map<String, Object> obj) {
+		return DataElement.isValid(obj);
+	}
+	
+	/**
 	 * Returns true if the given submodel element map is recognized as a MultiLanguageProperty
 	 */
 	public static boolean isMultiLanguageProperty(Map<String, Object> map) {
 		String modelType = ModelType.createAsFacade(map).getName();
 		// Either model type is set or the element type specific attributes are contained (fallback)
 		return MODELTYPE.equals(modelType)
-				|| (map.containsKey(VALUE) && map.containsKey(VALUE) && map.containsKey(VALUEID)
-						&& !map.containsKey(Property.VALUETYPE));
+				|| (modelType == null && (map.containsKey(VALUE) && map.containsKey(VALUE) && map.containsKey(VALUEID)
+						&& !map.containsKey(Property.VALUETYPE)));
 	}
 
 	@Override
@@ -73,4 +110,29 @@
 	protected KeyElements getKeyElement() {
 		return KeyElements.MULTILANGUAGEPROPERTY;
 	}
-}
\ No newline at end of file
+	
+	@SuppressWarnings("unchecked")
+	@Override
+	public void setValue(Object value) {
+		if(LangStrings.isLangStrings(value)) {
+			LangStrings strings = LangStrings.createAsFacade((Collection<Map<String, Object>>) value);
+			setValue(strings);
+		}
+		else {
+			throw new IllegalArgumentException("Given Object is not a LangStrings");
+		}
+	}
+
+	@Override
+	public MultiLanguageProperty getLocalCopy() {
+		// Return a shallow copy
+		MultiLanguageProperty copy = new MultiLanguageProperty();
+		copy.putAll(this);
+		return copy;
+	}
+
+	@Override
+	public void setValue(LangStrings value) {
+		put(VALUE, value);
+	}
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/Range.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/Range.java
deleted file mode 100644
index a608db2..0000000
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/Range.java
+++ /dev/null
@@ -1,81 +0,0 @@
-package org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement;
-
-import java.util.Map;
-
-import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
-import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IRange;
-import org.eclipse.basyx.submodel.metamodel.map.modeltype.ModelType;
-
-/**
- * A range element as defined in DAAS document
- * 
- * @author conradi
- *
- */
-public class Range extends DataElement implements IRange {
-
-	public static final String MODELTYPE = "Range";
-	public static final String VALUETYPE = "valueType";
-	public static final String MIN = "min";
-	public static final String MAX = "max";
-	
-
-	public Range() {
-		// Add model type
-		putAll(new ModelType(MODELTYPE));
-	}
-	
-	public Range(String valueType) {
-		this();
-		put(VALUETYPE, valueType);
-	}
-	
-	public Range(String valueType, Object min, Object max) {
-		this(valueType);
-		put(MIN, min);
-		put(MAX, max);
-	}
-	
-	/**
-	 * Creates a Range object from a map
-	 * 
-	 * @param obj a Range object as raw map
-	 * @return a Range object, that behaves like a facade for the given map
-	 */
-	public static Range createAsFacade(Map<String, Object> obj) {
-		Range facade = new Range();
-		facade.setMap(obj);
-		return facade;
-	}
-	
-	/**
-	 * Returns true if the given submodel element map is recognized as a Range element
-	 */
-	public static boolean isRange(Map<String, Object> map) {
-		String modelType = ModelType.createAsFacade(map).getName();
-		// Either model type is set or the element type specific attributes are contained (fallback)
-		return MODELTYPE.equals(modelType)
-				|| (map.containsKey(MIN) && map.containsKey(MAX) && map.containsKey(VALUETYPE));
-	}
-
-	@Override
-	public String getValueType() {
-		return (String) get(VALUETYPE);
-	}
-
-	@Override
-	public Object getMin() {
-		return get(MIN);
-	}
-
-	@Override
-	public Object getMax() {
-		return get(MAX);
-	}
-	
-	@Override
-	protected KeyElements getKeyElement() {
-		return KeyElements.RANGE;
-	}
-
-}
\ No newline at end of file
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/ReferenceElement.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/ReferenceElement.java
index d041e2d..52e2c52 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/ReferenceElement.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/ReferenceElement.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement;
 
 import java.util.Map;
@@ -28,8 +37,28 @@
 	public ReferenceElement() {
 		// Add model type
 		putAll(new ModelType(MODELTYPE));
+	}
 
-		put(Property.VALUE, null);
+	/**
+	 * Constructor with mandatory attribute
+	 * 
+	 * @param idShort
+	 */
+	public ReferenceElement(String idShort) {
+		super(idShort);
+		putAll(new ModelType(MODELTYPE));
+	}
+
+	/**
+	 * 
+	 * @param idShort
+	 * @param ref
+	 *            Reference to any other referable element of the same or any other
+	 *            AAS or a reference to an external object or entity
+	 */
+	public ReferenceElement(String idShort, Reference ref) {
+		this(idShort);
+		setValue(ref);
 	}
 
 	/**
@@ -50,6 +79,10 @@
 	 * @return a ReferenceElement object, that behaves like a facade for the given map
 	 */
 	public static ReferenceElement createAsFacade(Map<String, Object> obj) {
+		if (obj == null) {
+			return null;
+		}
+		
 		ReferenceElement ret = new ReferenceElement();
 		ret.setMap(obj);
 		return ret;
@@ -62,15 +95,11 @@
 		String modelType = ModelType.createAsFacade(map).getName();
 		// Either model type is set or the element type specific attributes are contained (fallback)
 		// Ambiguous - fallback could be further improved by parsing the value and recognizing references
-		return MODELTYPE.equals(modelType) || (map.containsKey(Property.VALUE) && !map.containsKey(Property.VALUETYPE)
+		return MODELTYPE.equals(modelType)
+				|| (modelType == null && (map.containsKey(Property.VALUE) && !map.containsKey(Property.VALUETYPE)
 				&& !map.containsKey(Property.VALUEID) && !map.containsKey(File.MIMETYPE)
 				&& !map.containsKey(SubmodelElementCollection.ORDERED)
-				&& !map.containsKey(SubmodelElementCollection.ALLOWDUPLICATES));
-	}
-
-	public void setValue(IReference ref) {
-		put(Property.VALUE, ref);
-		
+						&& !map.containsKey(SubmodelElementCollection.ALLOWDUPLICATES)));
 	}
 
 	@Override
@@ -79,9 +108,32 @@
 		return Reference.createAsFacade((Map<String, Object>) get(Property.VALUE));
 	}
 	
+	@SuppressWarnings("unchecked")
+	@Override
+	public void setValue(Object value) {
+		if(Reference.isReference(value)) {
+			setValue(Reference.createAsFacade((Map<String, Object>) value));
+		}
+		else {
+			throw new IllegalArgumentException("Given Object is not a Reference");
+		}
+	}
+	
 	@Override
 	protected KeyElements getKeyElement() {
 		return KeyElements.REFERENCEELEMENT;
 	}
 
+	@Override
+	public ReferenceElement getLocalCopy() {
+		// Return a shallow copy
+		ReferenceElement copy = new ReferenceElement();
+		copy.putAll(this);
+		return copy;
+	}
+
+	@Override
+	public void setValue(IReference value) {
+		put(Property.VALUE, value);
+	}
 }
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/property/AASLambdaPropertyHelper.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/property/AASLambdaPropertyHelper.java
index 568482b..a52d769 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/property/AASLambdaPropertyHelper.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/property/AASLambdaPropertyHelper.java
@@ -1,10 +1,19 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property;
 
 import java.util.function.Consumer;
 import java.util.function.Supplier;
 
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetypedef.PropertyValueTypeDef;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetypedef.PropertyValueTypeDefHelper;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueTypeHelper;
 import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaProvider;
 import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaProviderHelper;
 
@@ -25,7 +34,7 @@
 	 */
 	public static Property setLambdaValue(Property property, Supplier<Object> get, Consumer<Object> set) {
 		Object newValue = VABLambdaProviderHelper.createSimple(get, set);
-		PropertyValueTypeDef newType = PropertyValueTypeDefHelper.getType(get.get());
+		ValueType newType = ValueTypeHelper.getType(get.get());
 		property.set(newValue, newType);
 		return property;
 	}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/property/Property.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/property/Property.java
index d28e776..bb9ccc5 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/property/Property.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/property/Property.java
@@ -1,7 +1,17 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property;
 
 import java.util.Map;
 
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
 import org.eclipse.basyx.submodel.metamodel.api.parts.IConceptDescription;
 import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
 import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
@@ -12,8 +22,8 @@
 import org.eclipse.basyx.submodel.metamodel.map.qualifier.qualifiable.Qualifiable;
 import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.DataElement;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetypedef.PropertyValueTypeDef;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetypedef.PropertyValueTypeDefHelper;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueTypeHelper;
 import org.eclipse.basyx.vab.exception.provider.ProviderException;
 
 /**
@@ -39,6 +49,38 @@
 		put(Property.VALUE, null);
 		put(Property.VALUEID, null);
 	}
+	
+	/**
+	 * Constructor accepting only mandatory attribute
+	 * 
+	 * @param idShort
+	 * @param valueType
+	 */
+	public Property(String idShort, ValueType valueType) {
+		super(idShort);
+		setValueType(valueType);
+		setIdShort(idShort);
+		
+		// Add model type
+		putAll(new ModelType(MODELTYPE));
+	}
+	
+	/**
+	 * Constructor accepting an idShort and a value
+	 * The valueType is set automatically 
+	 * @param idShort the idShort for the Property
+	 * @param value the value for the Property
+	 */
+	public Property(String idShort, Object value) {
+		setIdShort(idShort);
+		
+		// Add model type
+		putAll(new ModelType(MODELTYPE));
+		
+		// Set the value for the Property
+		// set() also automatically sets the value type
+		setValue(value);
+	}
 
 	/**
 	 * Creates a Property object from a map
@@ -47,10 +89,27 @@
 	 * @return a Property object, that behaves like a facade for the given map
 	 */
 	public static Property createAsFacade(Map<String, Object> obj) {
+		if (obj == null) {
+			return null;
+		}
+		
+		if (!isValid(obj)) {
+			throw new MetamodelConstructionException(Property.class, obj);
+		}
+		
 		Property facade = new Property();
 		facade.setMap(obj);
 		return facade;
 	}
+	
+	/**
+	 * Check whether all mandatory elements for the metamodel
+	 * exist in a map
+	 * @return true/false
+	 */
+	public static boolean isValid(Map<String, Object> obj) {
+		return DataElement.isValid(obj) && obj.containsKey(Property.VALUETYPE);
+	}
 
 	/**
 	 * Returns true if the given submodel element map is recognized as a property
@@ -59,7 +118,7 @@
 		String modelType = ModelType.createAsFacade(map).getName();
 		// Either model type is set or the element type specific attributes are contained (fallback)
 		return MODELTYPE.equals(modelType)
-				|| (map.containsKey(VALUE) && map.containsKey(VALUETYPE));
+				|| (modelType == null && (map.containsKey(VALUE) && map.containsKey(VALUETYPE)));
 	}
 
 	/**
@@ -73,7 +132,7 @@
 		this();
 		// Put attributes
 		put(Property.VALUEID, null);
-		set(value);
+		setValue(value);
 	}
 
 	public Property(Object value, Referable referable, Reference semanticId, Qualifiable qualifiable) {
@@ -90,8 +149,11 @@
 	 * @param type
 	 *             manually determined type of the value
 	 */
-	public void setValueType(PropertyValueTypeDef type) {
-		put(Property.VALUETYPE, PropertyValueTypeDefHelper.getWrapper(type));
+	public void setValueType(ValueType type) {
+		if(type == null) {
+			throw new RuntimeException("Can not set null as valueType");
+		}
+		put(Property.VALUETYPE, type.toString());
 	}
 
 	public void setValueId(IReference ref) {
@@ -106,31 +168,25 @@
 		return Reference.createAsFacade((Map<String, Object>) get(VALUEID));
 	}
 
-	@Override
-	public void set(Object value) {
-		put(Property.VALUE, value);
-		put(Property.VALUETYPE, PropertyValueTypeDefHelper.getTypeWrapperFromObject(value));
-	}
-
 	/**
 	 * Sets the value and explicitly specifies the type of this value.
 	 * 
 	 * @throws ProviderException
 	 */
-	public void set(Object newValue, PropertyValueTypeDef newType) throws ProviderException {
+	public void set(Object newValue, ValueType newType) throws ProviderException {
 		put(Property.VALUE, newValue);
 		setValueType(newType);
 	}
 
-	@Override
-	public Object get() {
-		return get(Property.VALUE);
-	}
 
 	@Override
-	public String getValueType() {
-		PropertyValueTypeDef def = PropertyValueTypeDefHelper.readTypeDef(get(Property.VALUETYPE));
-		return def!=null ? def.toString() : "";
+	public ValueType getValueType() {
+		String valueType = (String) get(Property.VALUETYPE);
+		if (valueType == null) {
+			return null;
+		} else {
+			return ValueTypeHelper.fromName(valueType);
+		}
 	}
 
 	/**
@@ -142,11 +198,45 @@
 	 */
 	public void addConceptDescription(IConceptDescription description) {
 		Reference ref = new Reference(description, KeyElements.CONCEPTDESCRIPTION, true);
-		setSemanticID(ref);
+		setSemanticId(ref);
 	}
 
 	@Override
 	protected KeyElements getKeyElement() {
 		return KeyElements.PROPERTY;
 	}
+
+	@Override
+	public Object getValue() {
+		Object value = get(Property.VALUE);
+		if (value instanceof String) {
+			return ValueTypeHelper.getJavaObject(value, getValueType());
+		} else {
+			return value;
+		}
+	}
+	
+	@Override
+	public void setValue(Object value) {
+		put(Property.VALUE, ValueTypeHelper.prepareForSerialization(value));
+		// Value type is only set if it is not set before
+		if (getValueType() == null) {
+
+			// If valueType has not been set yet,
+			// a null can not be accepted as value, because valueType needs to be set
+			if (value == null) {
+				throw new RuntimeException("Can not set mandatory attribute 'valueType' with null as value");
+			}
+
+			put(Property.VALUETYPE, ValueTypeHelper.getType(value).toString());
+		}
+	}
+
+	@Override
+	public Property getLocalCopy() {
+		// Return a shallow copy
+		Property copy = new Property();
+		copy.putAll(this);
+		return copy;
+	}
 }
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/property/valuetype/ValueType.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/property/valuetype/ValueType.java
new file mode 100644
index 0000000..6377fd4
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/property/valuetype/ValueType.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype;
+
+import org.eclipse.basyx.submodel.metamodel.enumhelper.StandardizedLiteralEnum;
+import org.eclipse.basyx.submodel.metamodel.enumhelper.StandardizedLiteralEnumHelper;
+
+/**
+ * Helper enum to handle anySimpleTypeDef as defined in DAAS document <br />
+ * Represents the type of a data entry <br />
+ * TODO: Extend this to support rest of types (cf. p. 58)
+ * 
+ * @author schnicke
+ *
+ */
+public enum ValueType implements StandardizedLiteralEnum {
+	Int8("byte"), Int16("short"), Int32("int"), Int64("long"),
+	UInt8("unsignedByte"), UInt16("unsignedShort"), UInt32("unsignedInt"), UInt64("unsignedLong"),
+	String("string"), LangString("langString"),
+	AnyURI("anyuri"), Base64Binary("base64Binary"), HexBinary("hexBinary"), NOTATION("notation"), ENTITY("entity"), ID("id"), IDREF("idref"),
+	Integer("integer"), NonPositiveInteger("nonPositiveInteger"), NonNegativeInteger("nonNegativeInteger"), PositiveInteger("positiveInteger"), NegativeInteger("negativeInteger"),
+	Double("double"), Float("float"), Boolean("boolean"),
+	Duration("duration"), DayTimeDuration("dayTimeDuration"), YearMonthDuration("yearMonthDuration"),
+	DateTime("dateTime"), DateTimeStamp("dateTimeStamp"), GDay("gDay"), GMonth("gMonth"), GMonthDay("gMonthDay"), GYear("gYear"), GYearMonth("gYearMonth"),
+	QName("qName"),
+	None("none"), AnyType("anyType"), AnySimpleType("anySimpleType");
+
+	private String standardizedLiteral;
+
+	private ValueType(String standardizedLiteral) {
+		this.standardizedLiteral = standardizedLiteral;
+	}
+
+	@Override
+	public String getStandardizedLiteral() {
+		return standardizedLiteral;
+	}
+
+	@Override
+	public String toString() {
+		return standardizedLiteral;
+	}
+
+	public static ValueType fromString(String str) {
+		return StandardizedLiteralEnumHelper.fromLiteral(ValueType.class, str);
+	}
+
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/property/valuetype/ValueTypeHelper.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/property/valuetype/ValueTypeHelper.java
new file mode 100644
index 0000000..c3db504
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/property/valuetype/ValueTypeHelper.java
@@ -0,0 +1,244 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype;
+
+import java.math.BigInteger;
+import java.time.Duration;
+import java.time.Period;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.xml.datatype.DatatypeConfigurationException;
+import javax.xml.datatype.DatatypeFactory;
+import javax.xml.datatype.XMLGregorianCalendar;
+import javax.xml.namespace.QName;
+
+
+/**
+ * Provides utility functions for
+ * {@link org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType
+ * PropertyValueTypeDef} <br />
+ * * Creating a PropertyValueTypeDef from name <br/>
+ * * Creating a PropertyValueTypeDef for an object
+ * 
+ * @author schnicke
+ *
+ */
+public class ValueTypeHelper {
+	private static Map<String, ValueType> typeMap = new HashMap<>();
+
+	// insert all types into a Map to allow getting a PropertyValueType based on a
+	// String
+	static {
+		for (ValueType t : ValueType.values()) {
+			typeMap.put(t.toString(), t);
+		}
+	}
+	
+	// Strings required for meta-model conformant valueType format
+	private static final String TYPE_NAME = "name";
+	private static final String TYPE_OBJECT = "dataObjectType";
+
+	/**
+	 * Map the name of a PropertyValueTypeDef to a PropertyValueTypeDef
+	 * 
+	 * @param name
+	 * @return
+	 */
+	public static ValueType fromName(String name) {
+		if (typeMap.containsKey(name)) {
+			return typeMap.get(name);
+		} else {
+			throw new RuntimeException("Unknown type name " + name + "; can not handle this PropertyValueType");
+		}
+	}
+
+	/**
+	 * Creates the PropertyValueTypeDef for an arbitrary object
+	 * 
+	 * @param obj
+	 * @return
+	 */
+	public static ValueType getType(Object obj) {
+		ValueType objectType;
+		
+		if (obj == null) {
+			objectType = ValueType.None;
+		} else {
+			Class<?> c = obj.getClass();
+			if(c == byte.class || c == Byte.class) {
+				objectType = ValueType.Int8;
+			}else if(c == short.class || c == Short.class) {
+				objectType = ValueType.Int16;
+			}else if (c == int.class || c == Integer.class) {
+				objectType = ValueType.Integer;
+			} else if (c == long.class || c == Long.class) {
+				objectType = ValueType.Int64;
+			} else if (c == BigInteger.class) {
+				BigInteger tmp = (BigInteger) obj;
+				if (tmp.compareTo(new BigInteger("0")) > 0) {
+					objectType = ValueType.PositiveInteger;
+				} else if (tmp.compareTo(new BigInteger("0")) < 0) {
+					objectType = ValueType.NegativeInteger;
+				} else {
+					objectType = ValueType.NonNegativeInteger;
+				}
+
+			} else if (c == void.class || c == Void.class) {
+				objectType = ValueType.None;
+			} else if (c == boolean.class || c == Boolean.class) {
+				objectType = ValueType.Boolean;
+			} else if (c == float.class || c == Float.class) {
+				// TODO C# deprecated due to new serialization
+				objectType = ValueType.Float;
+			} else if (c == double.class || c == Double.class) {
+				objectType = ValueType.Double;
+			} else if (c == String.class) {
+				objectType = ValueType.String;
+			} else if (c == Duration.class) {
+				objectType = ValueType.Duration;
+			} else if (c == Period.class) {
+				objectType = ValueType.YearMonthDuration;
+			} else if (c == QName.class) {
+				objectType = ValueType.QName;
+			} else if (c == XMLGregorianCalendar.class) {
+				objectType = ValueType.DateTime;
+			} else {
+				throw new RuntimeException("Cannot map object " + obj + " to any PropertyValueTypeDef");
+			}
+		}
+		return objectType;
+	}
+
+	/**
+	 * Map the PropertyValueType to Java type
+	 * 
+	 */
+	public static Object getJavaObject(Object value, ValueType objType) {
+		Object target = null;
+		if(objType != null) {
+			switch(objType) {
+			case Int8:
+				if(((String)value).isEmpty()){
+					target = new Byte("NaN");
+				}else {
+					target = new Byte((String)value);
+				}
+				break;
+			case Int16: case UInt8:
+				if(((String)value).isEmpty()){
+					target = new Short("NaN");
+				}else {
+					target = new Short((String)value);
+				}
+				break;
+			case Int32: case UInt16:
+				if(((String)value).isEmpty()){
+					target = new Integer("NaN");
+				}else {
+					target = new Integer((String)value);
+				}
+				break;
+			case Int64: case UInt32:
+				if(((String)value).isEmpty()){
+					target = new Long("NaN");
+				}else {
+					target = new Long((String)value);
+				}
+				break;
+			case UInt64:
+				if(((String)value).isEmpty()){
+					target = new BigInteger("NaN");
+				}else {
+					target = new BigInteger((String)value);
+				}
+				break;
+			case Double:
+				if(((String)value).isEmpty()){
+					target = new Double("NaN");
+				}else {
+					target = new Double((String)value);
+				}
+				break;
+			case Float:
+				if(((String)value).isEmpty()){
+					target = new Float("NaN");
+				}else {
+					target =  new Float((String)value);
+				}
+				break;
+			case Boolean:
+				target =  new Boolean((String)value);
+				break;
+			case AnySimpleType: case String: case LangString: case AnyURI: case Base64Binary: case HexBinary: case NOTATION: case ENTITY: case ID: case IDREF:
+				target = (String) value;
+				break;
+			case Duration:		case DayTimeDuration:
+				target = Duration.parse((String)value);
+				break;
+			case YearMonthDuration:
+				target = Period.parse((String)value);
+				break;
+			case DateTime: case DateTimeStamp: case GDay: case GMonth: case GMonthDay: case GYear: case GYearMonth:
+				try {
+					target = DatatypeFactory.newInstance().newXMLGregorianCalendar((String)value);
+					break;
+				} catch (DatatypeConfigurationException e) {
+					e.printStackTrace();
+					throw new RuntimeException("Could not create DatatypeFactory for XMLGregorianCaldner handling");
+				} 
+			case QName:
+				target = QName.valueOf((String)value);
+				break;
+			default:
+				target = value;
+				break;
+			}
+			return target;
+		}else {
+			return null;
+		}
+		
+		
+	}
+
+	/**
+	 * Convert an object which has special types (Duration, period, Qname, Date) to
+	 * String object Used by Property.set() or ConnectedProperty.set(), prepare for the serialization
+	 * 
+	 * @param value - the target object
+	 * @return
+	 */
+	public static Object prepareForSerialization(Object value) {
+		if(value != null) {
+			Class<?> c = value.getClass();
+			if (c == Duration.class || c == Period.class || c == QName.class || c == XMLGregorianCalendar.class) {
+				return value.toString();
+			}
+		}
+			return value;
+
+	}
+
+	@SuppressWarnings("unchecked")
+	public static ValueType readTypeDef(Object vTypeMap) {
+		if (vTypeMap instanceof String) {
+			// From xml/json-schema point of view, this should be only a string.
+			return fromName((String) vTypeMap);
+		} else if (vTypeMap instanceof Map<?, ?>) {
+			// Reading still supported, but should be a simple string
+			Map<String, Object> map = (Map<String, Object>) vTypeMap;
+			Map<String, Object> dot = (Map<String, Object>) map.get(TYPE_OBJECT);
+
+			return fromName(dot.get(TYPE_NAME).toString());
+		}
+		return null;
+	}
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/property/valuetypedef/PropertyValueTypeDef.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/property/valuetypedef/PropertyValueTypeDef.java
deleted file mode 100644
index 61c4022..0000000
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/property/valuetypedef/PropertyValueTypeDef.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetypedef;
-
-import org.eclipse.basyx.submodel.metamodel.enumhelper.StandardizedLiteralEnum;
-import org.eclipse.basyx.submodel.metamodel.enumhelper.StandardizedLiteralEnumHelper;
-
-/**
- * Helper enum to handle anySimpleTypeDef as defined in DAAS document <br />
- * Represents the type of a data entry <br />
- * TODO: Extend this to support rest of types (cf. p. 58)
- * 
- * @author schnicke
- *
- */
-public enum PropertyValueTypeDef implements StandardizedLiteralEnum {
-	Double("double"), Float("float"), Integer("int"), String("string"), Boolean("boolean"), Void("void"), Null("null");
-
-	private String standardizedLiteral;
-
-	private PropertyValueTypeDef(String standardizedLiteral) {
-		this.standardizedLiteral = standardizedLiteral;
-	}
-
-	@Override
-	public String getStandardizedLiteral() {
-		return standardizedLiteral;
-	}
-
-	@Override
-	public String toString() {
-		return standardizedLiteral;
-	}
-
-	public static PropertyValueTypeDef fromString(String str) {
-		return StandardizedLiteralEnumHelper.fromLiteral(PropertyValueTypeDef.class, str);
-	}
-
-}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/property/valuetypedef/PropertyValueTypeDefHelper.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/property/valuetypedef/PropertyValueTypeDefHelper.java
deleted file mode 100644
index 4025801..0000000
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/property/valuetypedef/PropertyValueTypeDefHelper.java
+++ /dev/null
@@ -1,118 +0,0 @@
-package org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetypedef;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Provides utility functions for
- * {@link org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetypedef.PropertyValueTypeDef
- * PropertyValueTypeDef} <br />
- * * Creating a PropertyValueTypeDef from name <br/>
- * * Creating a PropertyValueTypeDef for an object
- * 
- * @author schnicke
- *
- */
-public class PropertyValueTypeDefHelper {
-	private static Map<String, PropertyValueTypeDef> typeMap = new HashMap<>();
-
-	// insert all types into a Map to allow getting a PropertyValueType based on a
-	// String
-	static {
-		for (PropertyValueTypeDef t : PropertyValueTypeDef.values()) {
-			typeMap.put(t.toString(), t);
-		}
-	}
-	
-	// Strings required for meta-model conformant valueType format
-	private static final String TYPE_NAME = "name";
-	private static final String TYPE_OBJECT = "dataObjectType";
-
-	/**
-	 * Map the name of a PropertyValueTypeDef to a PropertyValueTypeDef
-	 * 
-	 * @param name
-	 * @return
-	 */
-	public static PropertyValueTypeDef fromName(String name) {
-		if (typeMap.containsKey(name)) {
-			return typeMap.get(name);
-		} else {
-			throw new RuntimeException("Unknown type name " + name + "; can not handle this PropertyValueType");
-		}
-	}
-
-	/**
-	 * Creates the appropriate type map for a given object
-	 * 
-	 * @param obj
-	 * @return
-	 */
-	public static Map<String, Object> getTypeWrapperFromObject(Object obj) {
-		return getWrapper(getType(obj));
-	}
-
-	/**
-	 * Creates the PropertyValueTypeDef for an arbitrary object
-	 * 
-	 * @param obj
-	 * @return
-	 */
-	public static PropertyValueTypeDef getType(Object obj) {
-		PropertyValueTypeDef objectType;
-		
-		if (obj == null) {
-			objectType = PropertyValueTypeDef.Null;
-		} else {
-			Class<?> c = obj.getClass();
-			if (c == int.class || c == Integer.class) {
-				objectType = PropertyValueTypeDef.Integer;
-			} else if (c == void.class || c == Void.class) {
-				objectType = PropertyValueTypeDef.Void;
-			} else if (c == boolean.class || c == Boolean.class) {
-				objectType = PropertyValueTypeDef.Boolean;
-			} else if (c == float.class || c == Float.class) {
-				// TODO C# deprecated due to new serialization
-				objectType = PropertyValueTypeDef.Float;
-			} else if (c == double.class || c == Double.class) {
-				objectType = PropertyValueTypeDef.Double;
-			} else if (c == String.class) {
-				objectType = PropertyValueTypeDef.String;
-			} else {
-				throw new RuntimeException("Cannot map object " + obj + " to any PropertyValueTypeDef");
-			}
-		}
-		return objectType;
-	}
-
-	/**
-	 * Creates the appropriate type map for a given type
-	 * 
-	 * @param type
-	 * @return
-	 */
-	public static Map<String, Object> getWrapper(PropertyValueTypeDef type) {
-		HashMap<String, Object> valueTypeWrapper = new HashMap<>();
-		HashMap<String, Object> dataObjectTypeWrapper = new HashMap<>();
-		valueTypeWrapper.put(TYPE_OBJECT, dataObjectTypeWrapper);
-		dataObjectTypeWrapper.put(TYPE_NAME, type.toString());
-		return valueTypeWrapper;
-	}
-
-	@SuppressWarnings("unchecked")
-	public static PropertyValueTypeDef readTypeDef(Object vTypeMap) {
-		
-		if (vTypeMap instanceof Map<?,?>) {
-
-			Map<String, Object> map = (Map<String, Object>) vTypeMap;
-			Map<String, Object> dot = (Map<String, Object>) map.get(TYPE_OBJECT);
-			
-			return fromName(dot.get(TYPE_NAME).toString());
-			
-		} else if (vTypeMap instanceof String) {
-			// From xml/json-schema point of view, this should be only a string.
-			return fromName((String)vTypeMap);
-		}
-		return null;
-	}
-}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/range/Range.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/range/Range.java
new file mode 100644
index 0000000..fbdf1d6
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/range/Range.java
@@ -0,0 +1,172 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.range;
+
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IRange;
+import org.eclipse.basyx.submodel.metamodel.map.modeltype.ModelType;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.DataElement;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueTypeHelper;
+
+/**
+ * A range element as defined in DAAS document
+ * 
+ * @author conradi
+ *
+ */
+public class Range extends DataElement implements IRange {
+
+	public static final String MODELTYPE = "Range";
+	public static final String VALUETYPE = "valueType";
+	public static final String MIN = "min";
+	public static final String MAX = "max";
+	
+
+	public Range() {
+		// Add model type
+		putAll(new ModelType(MODELTYPE));
+	}
+	
+	public Range(ValueType valueType) {
+		this();
+		setValueType(valueType);
+	}
+
+	/**
+	 * Constructor accepting only mandatory attribute
+	 * @param idShort
+	 * @param valueType
+	 */
+	public Range(String idShort, ValueType valueType) {
+		super(idShort);
+		// Add model type
+		putAll(new ModelType(MODELTYPE));
+		setValueType(valueType);
+	}
+	
+	public Range(ValueType valueType, Object min, Object max) {
+		this(valueType);
+		put(MIN, min);
+		put(MAX, max);
+	}
+	
+	/**
+	 * Creates a Range object from a map
+	 * 
+	 * @param obj a Range object as raw map
+	 * @return a Range object, that behaves like a facade for the given map
+	 */
+	public static Range createAsFacade(Map<String, Object> obj) {
+		if (obj == null) {
+			return null;
+		}
+		
+		if (!isValid(obj)) {
+			throw new MetamodelConstructionException(Range.class, obj);
+		}
+		
+		Range facade = new Range();
+		facade.setMap(obj);
+		return facade;
+	}
+	
+	/**
+	 * Check whether all mandatory elements for the metamodel
+	 * exist in a map
+	 * @return true/false
+	 */
+	public static boolean isValid(Map<String, Object> obj) {
+		return DataElement.isValid(obj) && obj.containsKey(VALUETYPE);
+	}
+	
+	/**
+	 * Returns true if the given submodel element map is recognized as a Range element
+	 */
+	public static boolean isRange(Map<String, Object> map) {
+		String modelType = ModelType.createAsFacade(map).getName();
+		// Either model type is set or the element type specific attributes are contained (fallback)
+		return MODELTYPE.equals(modelType)
+				|| (modelType == null && (map.containsKey(MIN) && map.containsKey(MAX) && map.containsKey(VALUETYPE)));
+	}
+
+	private void setValueType(ValueType valueType) {
+		put(Range.VALUETYPE, valueType.toString());
+	}
+
+	@Override
+	public ValueType getValueType() {
+		return ValueTypeHelper.readTypeDef(get(Range.VALUETYPE));
+	}
+
+	@Override
+	public Object getMin() {
+		Object value = get(MIN);
+		if(value instanceof String) {
+			return ValueTypeHelper.getJavaObject(value, getValueType());
+		}else {
+			return value;
+		}
+	}
+
+	@Override
+	public Object getMax() {
+		Object value = get(MAX);
+		if(value instanceof String) {
+			return ValueTypeHelper.getJavaObject(value, getValueType());
+		}else {
+			return value;
+		}
+	}
+	
+	@Override
+	protected KeyElements getKeyElement() {
+		return KeyElements.RANGE;
+	}
+
+	@Override
+	public RangeValue getValue() {
+		return new RangeValue(getMin(), getMax());
+	}
+	
+	@SuppressWarnings("unchecked")
+	@Override
+	public void setValue(Object value) {
+		if(RangeValue.isRangeValue(value)) {
+			RangeValue rv = RangeValue.createAsFacade((Map<String, Object>) value);
+			setValue(rv);
+		} else {
+			throw new IllegalArgumentException("Given Object is not a RangeValue");
+		}
+	}
+
+	@Override
+	public void setValue(RangeValue rv) {
+		Object minValue = rv.getMin();
+		Object maxValue = rv.getMax();
+
+		put(Range.MIN, ValueTypeHelper.prepareForSerialization(minValue));
+		put(Range.MAX, ValueTypeHelper.prepareForSerialization(maxValue));
+		if (getValueType() == null) {
+			setValueType(ValueTypeHelper.getType(minValue));
+		}
+	}
+
+	@Override
+	public Range getLocalCopy() {
+		// Return a shallow copy
+		Range copy = new Range();
+		copy.putAll(this);
+		return copy;
+	}
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/range/RangeValue.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/range/RangeValue.java
new file mode 100644
index 0000000..322bcac
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/range/RangeValue.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.range;
+
+import java.util.Map;
+
+import org.eclipse.basyx.vab.model.VABModelMap;
+
+
+/**
+ * Container class for holding the value of Range
+ * 
+ * @author conradi
+ *
+ */
+public class RangeValue extends VABModelMap<Object> {
+
+	private RangeValue() {}
+	
+	public RangeValue(Object min, Object max) {
+		put(Range.MIN, min);
+		put(Range.MAX, max);
+	}
+	
+	@SuppressWarnings("unchecked")
+	public static boolean isRangeValue(Object value) {
+		
+		// Given Object must be a Map
+		if(!(value instanceof Map<?, ?>)) {
+			return false;
+		}
+		
+		Map<String, Object> map = (Map<String, Object>) value;
+		
+		// Given Map must contain all necessary Entries
+		return map.containsKey(Range.MIN) && map.containsKey(Range.MAX);
+	}
+	
+	/**
+	 * Creates a RangeValue object from a map
+	 * 
+	 * @param obj a RangeValue object as raw map
+	 * @return a RangeValue object, that behaves like a facade for the given map
+	 */
+	public static RangeValue createAsFacade(Map<String, Object> obj) {
+		if (obj == null) {
+			return null;
+		}
+		
+		RangeValue facade = new RangeValue();
+		facade.setMap(obj);
+		return facade;
+	}
+	
+	public Object getMin() {
+		return get(Range.MIN);
+	}
+	
+	public Object getMax() {
+		return get(Range.MAX);
+	}
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/entity/Entity.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/entity/Entity.java
index 4741f09..333b87f 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/entity/Entity.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/entity/Entity.java
@@ -1,9 +1,19 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.map.submodelelement.entity;
 
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Map;
 
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
 import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
 import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
 import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
@@ -32,6 +42,19 @@
 		putAll(new ModelType(MODELTYPE));
 	}
 	
+	/**
+	 * Constructor accepting only mandatory attribute
+	 * @param idShort
+	 * @param entityType
+	 */
+	public Entity(String idShort, EntityType entityType) {
+		super(idShort);
+		setEntityType(entityType);
+		
+		// Add model type
+		putAll(new ModelType(MODELTYPE));
+	}
+	
 	public Entity(EntityType entityType, Collection<ISubmodelElement> statements, IReference asset) {
 		this();
 		setEntityType(entityType);
@@ -51,6 +74,12 @@
 		put(ENTITY_TYPE, entityType.toString());
 	}
 
+	public static boolean isEntity(Map<String, Object> map) {
+		String modelType = ModelType.createAsFacade(map).getName();
+		// Either model type is set or the element type specific attributes are contained (fallback)
+		return MODELTYPE.equals(modelType) || (modelType == null && map.containsKey(Entity.STATEMENT));
+	}
+
 	/**
 	 * Creates an Entity object from a map
 	 * 
@@ -58,10 +87,27 @@
 	 * @return an Entity object, that behaves like a facade for the given map
 	 */
 	public static Entity createAsFacade(Map<String, Object> obj) {
+		if (obj == null) {
+			return null;
+		}
+		
+		if (!isValid(obj)) {
+			throw new MetamodelConstructionException(Entity.class, obj);
+		}
+		
 		Entity facade = new Entity();
 		facade.setMap(obj);
 		return facade;
 	}
+	
+	/**
+	 * Check whether all mandatory elements for the metamodel
+	 * exist in a map
+	 * @return true/false
+	 */
+	public static boolean isValid(Map<String, Object> obj) {
+		return SubmodelElement.isValid(obj) && obj.containsKey(ENTITY_TYPE);
+	}
 
 	@Override
 	@SuppressWarnings("unchecked")
@@ -91,4 +137,29 @@
 		return KeyElements.ENTITY;
 	}
 
+	@Override
+	public EntityValue getValue() {
+		return new EntityValue(getStatements(), getAsset());
+	}
+	
+	@SuppressWarnings("unchecked")
+	@Override
+	public void setValue(Object value) {
+		if(EntityValue.isEntityValue(value)) {
+			EntityValue ev = EntityValue.createAsFacade((Map<String, Object>) value);
+			put(Entity.STATEMENT, ev.getStatement());
+			put(Entity.ASSET, ev.getAsset());
+		}
+		else {
+			throw new IllegalArgumentException("Given Object is not an EntityValue");
+		}
+	}
+
+	@Override
+	public Entity getLocalCopy() {
+		// Return a shallow copy
+		Entity copy = new Entity();
+		copy.putAll(this);
+		return copy;
+	}
 }
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/entity/EntityValue.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/entity/EntityValue.java
new file mode 100644
index 0000000..cdce0a7
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/entity/EntityValue.java
@@ -0,0 +1,93 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.metamodel.map.submodelelement.entity;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.facade.submodelelement.SubmodelElementFacadeFactory;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
+import org.eclipse.basyx.vab.model.VABModelMap;
+
+
+/**
+ * Container class for holding the value of Entity
+ * 
+ * @author conradi
+ *
+ */
+public class EntityValue extends VABModelMap<Object> {
+
+	private EntityValue() {}
+	
+	public EntityValue(Collection<ISubmodelElement> statements, IReference asset) {
+		put(Entity.STATEMENT, statements);
+		put(Entity.ASSET, asset);
+	}
+	
+	/**
+	 * Creates a EntityValue object from a map
+	 * 
+	 * @param obj a EntityValue object as raw map
+	 * @return a EntityValue object, that behaves like a facade for the given map
+	 */
+	public static EntityValue createAsFacade(Map<String, Object> obj) {
+		if (obj == null) {
+			return null;
+		}
+		
+		EntityValue facade = new EntityValue();
+		facade.setMap(obj);
+		return facade;
+	}
+	
+	@SuppressWarnings("unchecked")
+	public static boolean isEntityValue(Object value) {
+		
+		// Given Object must be a Map
+		if(!(value instanceof Map<?, ?>)) {
+			return false;
+		}
+		
+		Map<String, Object> map = (Map<String, Object>) value;
+		
+		// Given Map must contain all necessary Entries
+		if(!(map.get(Entity.STATEMENT) instanceof Collection<?> 
+				&& Reference.isReference(map.get(Entity.ASSET)))) {
+			return false;
+		}
+		
+		try {
+			// Try to create a Facade for each Element
+			// If one of the Objects in STATEMENT is not a smElement,
+			// SubmodelElementFacadeFactory throws an Exception
+			((Collection<Map<String, Object>>) map.get(Entity.STATEMENT)).stream()
+				.forEach(SubmodelElementFacadeFactory::createSubmodelElement);
+		} catch (RuntimeException e) {
+			return false;
+		}
+		
+		return true;
+	}
+	
+	@SuppressWarnings("unchecked")
+	public Collection<ISubmodelElement> getStatement() {
+		Collection<Map<String, Object>> elements = (Collection<Map<String, Object>>) get(Entity.STATEMENT);
+		return elements.stream().map(e -> SubmodelElementFacadeFactory.createSubmodelElement(e)).collect(Collectors.toList());
+	}
+	
+	@SuppressWarnings("unchecked")
+	public IReference getAsset() {
+		return Reference.createAsFacade((Map<String, Object>) get(Entity.ASSET));
+	}
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/event/BasicEvent.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/event/BasicEvent.java
index cac3aaf..f04bd0b 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/event/BasicEvent.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/event/BasicEvent.java
@@ -1,7 +1,17 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.map.submodelelement.event;
 
 import java.util.Map;
 
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
 import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
 import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
 import org.eclipse.basyx.submodel.metamodel.api.submodelelement.event.IBasicEvent;
@@ -30,6 +40,19 @@
 		put(OBSERVED, observed);
 	}
 	
+	/**
+	 * Constructor accepting only mandatory attribute
+	 * @param idShort
+	 * @param observed
+	 */
+	public BasicEvent(String idShort, IReference observed) {
+		super(idShort);
+		
+		// Add model type
+		putAll(new ModelType(MODELTYPE));
+		put(OBSERVED, observed);
+	}
+	
 	@Override
 	protected KeyElements getKeyElement() {
 		return KeyElements.BASICEVENT;
@@ -42,18 +65,35 @@
 	 * @return a BasicEvent object, that behaves like a facade for the given map
 	 */
 	public static BasicEvent createAsFacade(Map<String, Object> obj) {
+		if (obj == null) {
+			return null;
+		}
+		
+		if (!isValid(obj)) {
+			throw new MetamodelConstructionException(BasicEvent.class, obj);			
+		}
+		
 		BasicEvent facade = new BasicEvent();
 		facade.setMap(obj);
 		return facade;
 	}
 	
 	/**
+	 * Check whether all mandatory elements for the metamodel
+	 * exist in a map
+	 * @return true/false
+	 */
+	public static boolean isValid(Map<String, Object> obj) {
+		return SubmodelElement.isValid(obj) && obj.containsKey(OBSERVED);
+	}
+	
+	/**
 	 * Returns true if the given submodel element map is recognized as an BasicEvent element
 	 */
 	public static boolean isBasicEvent(Map<String, Object> map) {
 		String modelType = ModelType.createAsFacade(map).getName();
 		// Either model type is set or the element type specific attributes are contained (fallback)
-		return MODELTYPE.equals(modelType) || map.containsKey(OBSERVED);
+		return MODELTYPE.equals(modelType) || (modelType == null && map.containsKey(OBSERVED));
 	}
 
 	@Override
@@ -61,4 +101,28 @@
 	public IReference getObserved() {
 		return Reference.createAsFacade((Map<String, Object>) get(OBSERVED));
 	}
+
+	@Override
+	public IReference getValue() {
+		return getObserved();
+	}
+	
+	@SuppressWarnings("unchecked")
+	@Override
+	public void setValue(Object value) {
+		if(Reference.isReference(value)) {
+			put(OBSERVED, Reference.createAsFacade((Map<String, Object>) value));
+		}
+		else {
+			throw new IllegalArgumentException("Given Object is not a Reference");
+		}
+	}
+
+	@Override
+	public BasicEvent getLocalCopy() {
+		// Return a shallow copy
+		BasicEvent copy = new BasicEvent();
+		copy.putAll(this);
+		return copy;
+	}
 }
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/operation/AsyncInvocation.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/operation/AsyncInvocation.java
new file mode 100644
index 0000000..193818c
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/operation/AsyncInvocation.java
@@ -0,0 +1,97 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation;
+
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Function;
+
+import org.apache.poi.ss.formula.functions.T;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IAsyncInvocation;
+
+/**
+ * Local implementation of IAsyncInvocation.
+ * 
+ * @author conradi, espen
+ *
+ */
+public class AsyncInvocation implements IAsyncInvocation {
+	// Delayer for timeouts
+	private static ScheduledThreadPoolExecutor delayer = new ScheduledThreadPoolExecutor(0);
+
+	private String operationId;
+	private CompletableFuture<Void> future;
+	private Object result;
+	private RuntimeException exception;
+	
+	@SuppressWarnings("unchecked")
+	public AsyncInvocation(Operation operation, int timeout, Object... parameters) {
+		operationId = operation.getIdShort();
+		
+		Function<Object[], Object> invokable = (Function<Object[], Object>) operation.get(Operation.INVOKABLE);
+		future = CompletableFuture.supplyAsync(
+				// Run Operation asynchronously
+				() -> invokable.apply(parameters))
+				// Accept either result or throw exception on timeout
+				.acceptEither(setTimeout(timeout),
+					// result accepted => write result (or timeout exception)
+						futureResult -> this.result = futureResult
+				).exceptionally(throwable -> {
+					// result not accepted? set operation state
+					if (throwable.getCause() instanceof OperationExecutionTimeoutException) {
+						exception = (RuntimeException) throwable.getCause();
+					} else {
+						// result not accepted? set operation state
+						exception = new OperationExecutionErrorException(
+								"Exception while executing Operation Operation '" + operationId + "'", throwable);
+					}
+					return null;
+				});
+	}
+	
+	/**
+	 * Function for scheduling a timeout function with completable futures
+	 */
+	private CompletableFuture<T> setTimeout(int timeout) {
+		CompletableFuture<T> timeoutFuture = new CompletableFuture<>();
+		delayer.schedule(
+				() -> timeoutFuture.completeExceptionally(
+						new OperationExecutionTimeoutException("Operation " + operationId + " timed out")),
+				timeout, TimeUnit.MILLISECONDS);
+		return timeoutFuture;
+	}
+
+	@Override
+	public Object getResult() {
+		try {
+			future.get();
+		} catch (Exception e) {
+			// Some RuntimeException occured when finishing the future
+			throw new OperationExecutionErrorException(
+					"Exception while executing Operation Operation '" + operationId + "'", e.getCause());
+		}
+		if (exception instanceof OperationExecutionTimeoutException
+				|| exception instanceof OperationExecutionErrorException) {
+			// Future finished with an exception
+			throw exception;
+		}
+		return result;
+	}
+	
+	@Override
+	public boolean isFinished() {
+		return future.isDone();
+	}
+
+	public String getOperationId() {
+		return operationId;
+	}
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/operation/Operation.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/operation/Operation.java
index cbbcdd7..1568c82 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/operation/Operation.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/operation/Operation.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation;
 
 import java.util.ArrayList;
@@ -5,8 +14,10 @@
 import java.util.Map;
 import java.util.function.Function;
 
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
 import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
 import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IAsyncInvocation;
 import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperation;
 import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperationVariable;
 import org.eclipse.basyx.submodel.metamodel.map.modeltype.ModelType;
@@ -14,6 +25,7 @@
 import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangStrings;
 import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElement;
+import org.eclipse.basyx.vab.exception.provider.WrongNumberOfParametersException;
 
 /**
  * Operation as defined in DAAS document <br/>
@@ -23,12 +35,17 @@
  *
  */
 public class Operation extends SubmodelElement implements IOperation {
+	// Default timeout for asynchronous operation calls
+	public static final int DEFAULT_ASYNC_TIMEOUT = 10000;
+
 	public static final String IN = "inputVariables";
 	public static final String OUT = "outputVariables";
 	public static final String INOUT = "inoutputVariables";
 
 	public static final String INVOKABLE = "invokable";
 	public static final String MODELTYPE = "Operation";
+	
+	public static final String INVOKE = "invoke";
 
 	/**
 	 * Constructor
@@ -45,9 +62,25 @@
 
 		// Variables, that are input and output
 		put(INOUT, new ArrayList<OperationVariable>());
+	}
+	
+	/**
+	 * Constructor accepting only mandatory attribute
+	 * @param idShort
+	 */
+	public Operation(String idShort) {
+		super(idShort);
+		// Add model type
+		putAll(new ModelType(MODELTYPE));
 
-		// Extension of DAAS specification for function storage
-		put(INVOKABLE, null);
+		// Input variables
+		setInputVariables(new ArrayList<OperationVariable>());
+
+		// Output variables
+		setOutputVariables(new ArrayList<OperationVariable>());
+
+		// Variables, that are input and output
+		setInOutputVariables(new ArrayList<OperationVariable>());
 	}
 
 	/**
@@ -89,7 +122,7 @@
 	 */
 	public Operation(Function<Object[], Object> function) {
 		this();
-		setInvocable(function);
+		setInvokable(function);
 	}
 
 	/**
@@ -100,18 +133,43 @@
 	 * @return an Operation object, that behaves like a facade for the given map
 	 */
 	public static Operation createAsFacade(Map<String, Object> obj) {
+		if (obj == null) {
+			return null;
+		}
+		
+		if (!isValid(obj)) {
+			throw new MetamodelConstructionException(Operation.class, obj);
+		}
+		
 		Operation ret = new Operation();
 		ret.setMap(obj);
 		return ret;
 	}
+	
+	/**
+	 * Check whether all mandatory elements for the metamodel
+	 * exist in a map
+	 * @return true/false
+	 */
+	public static boolean isValid(Map<String, Object> obj) {
+		return SubmodelElement.isValid(obj);
+	}
 
 	/**
 	 * Returns true if the given submodel element map is recognized as an operation
 	 */
-	public static boolean isOperation(Map<String, Object> map) {
+	@SuppressWarnings("unchecked")
+	public static boolean isOperation(Object value) {
+		if(!(value instanceof Map<?, ?>)) {
+			return false;
+		}
+		
+		Map<String, Object> map = (Map<String, Object>) value;
+		
 		String modelType = ModelType.createAsFacade(map).getName();
 		// Either model type is set or the element type specific attributes are contained
-		return MODELTYPE.equals(modelType) || (map.containsKey(IN) && map.containsKey(OUT) && map.containsKey(INOUT));
+		return MODELTYPE.equals(modelType)
+				|| (modelType == null && (map.containsKey(IN) && map.containsKey(OUT) && map.containsKey(INOUT)));
 	}
 
 	@Override
@@ -145,10 +203,29 @@
 
 	@SuppressWarnings("unchecked")
 	@Override
-	public Object invoke(Object... params) throws Exception {
+	public Object invoke(Object... params) {
+		if (params.length != getInputVariables().size()) {
+			throw new WrongNumberOfParametersException(getIdShort(), getInputVariables(), params);
+		}
 		return ((Function<Object[], Object>) get(INVOKABLE)).apply(params);
 	}
 
+	@Override
+	public SubmodelElement[] invoke(SubmodelElement... elems) {
+		throw new UnsupportedOperationException(
+				"SubmodelElement matching logic is only supported for connected Operations");
+	}
+
+	@Override
+	public AsyncInvocation invokeAsync(Object... params) {
+		return new AsyncInvocation(this, 10000, params);
+	}
+
+	@Override
+	public IAsyncInvocation invokeAsyncWithTimeout(int timeout, Object... params) {
+		return new AsyncInvocation(this, timeout, params);
+	}
+
 	public void setInputVariables(Collection<OperationVariable> in) {
 		put(Operation.IN, in);
 	}
@@ -161,7 +238,7 @@
 		put(Operation.INOUT, inOut);
 	}
 
-	public void setInvocable(Function<Object[], Object> endpoint) {
+	public void setInvokable(Function<Object[], Object> endpoint) {
 		put(Operation.INVOKABLE, endpoint);
 	}
 
@@ -194,4 +271,37 @@
 	protected KeyElements getKeyElement() {
 		return KeyElements.OPERATION;
 	}
+
+	@Override
+	public Object getValue() {
+		throw new UnsupportedOperationException("An Operation has no value");
+	}
+
+	@Override
+	public void setValue(Object value) {
+		throw new UnsupportedOperationException("An Operation has no value");
+	}
+
+	@Override
+	public Operation getLocalCopy() {
+		// Create a shallow copy
+		Operation copy = new Operation();
+		copy.putAll(this);
+		// Copy InputVariables
+		Collection<IOperationVariable> inVars = copy.getInputVariables();
+		Collection<OperationVariable> inVarCopy = new ArrayList<>();
+		inVars.stream().forEach(v -> inVarCopy.add(new OperationVariable(v.getValue().getLocalCopy())));
+		copy.setInputVariables(inVarCopy);
+		// Copy OutputVariables
+		Collection<IOperationVariable> outVars = copy.getOutputVariables();
+		Collection<OperationVariable> outVarCopy = new ArrayList<>();
+		outVars.stream().forEach(v -> outVarCopy.add(new OperationVariable(v.getValue().getLocalCopy())));
+		copy.setOutputVariables(outVarCopy);
+		// Copy Input/Output-Variables
+		Collection<IOperationVariable> inoutVars = copy.getInOutputVariables();
+		Collection<OperationVariable> inoutVarCopy = new ArrayList<>();
+		inoutVars.stream().forEach(v -> inoutVarCopy.add(new OperationVariable(v.getValue().getLocalCopy())));
+		copy.setInOutputVariables(inoutVarCopy);
+		return copy;
+	}
 }
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/operation/OperationExecutionErrorException.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/operation/OperationExecutionErrorException.java
new file mode 100644
index 0000000..a3bf951
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/operation/OperationExecutionErrorException.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation;
+
+/**
+ * Used to indicate that the execution of an Operation failed
+ * 
+ * @author conradi
+ *
+ */
+public class OperationExecutionErrorException extends RuntimeException {
+
+	
+	/**
+	 * Version information for serialized instances
+	 */
+	private static final long serialVersionUID = 1L;
+	
+	
+	/**
+	 * Store message
+	 */
+	protected String message = null;
+	
+	
+	/**
+	 * Constructor
+	 */
+	public OperationExecutionErrorException(String msg) {
+		// Store message
+		message = msg;
+	}
+	
+		
+	public OperationExecutionErrorException(Exception e) {
+		super(e);
+	}
+
+
+	public OperationExecutionErrorException(String message, Throwable cause) {
+		super(cause);
+		this.message = message;
+	}
+
+
+	/**
+	 * Return detailed message
+	 */
+	@Override
+	public String getMessage() {
+		return message;
+	}
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/operation/OperationExecutionTimeoutException.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/operation/OperationExecutionTimeoutException.java
new file mode 100644
index 0000000..4ad5021
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/operation/OperationExecutionTimeoutException.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation;
+
+/**
+ * Used to indicate that the execution of an Operation timed out
+ * 
+ * @author espen
+ *
+ */
+public class OperationExecutionTimeoutException extends RuntimeException {
+
+	
+	/**
+	 * Version information for serialized instances
+	 */
+	private static final long serialVersionUID = 1L;
+	
+	
+	/**
+	 * Store message
+	 */
+	protected String message = null;
+	
+	
+	/**
+	 * Constructor
+	 */
+	public OperationExecutionTimeoutException(String msg) {
+		// Store message
+		message = msg;
+	}
+	
+		
+	public OperationExecutionTimeoutException(Exception e) {
+		super(e);
+	}
+
+
+	public OperationExecutionTimeoutException(String message, Throwable cause) {
+		super(cause);
+		this.message = message;
+	}
+
+
+	/**
+	 * Return detailed message
+	 */
+	@Override
+	public String getMessage() {
+		return message;
+	}
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/operation/OperationHelper.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/operation/OperationHelper.java
index 800e874..cee7219 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/operation/OperationHelper.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/operation/OperationHelper.java
@@ -1,11 +1,20 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation;
 
 import org.eclipse.basyx.submodel.metamodel.api.qualifier.haskind.ModelingKind;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetypedef.PropertyValueTypeDef;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
 
 public class OperationHelper {
-	public static Property createPropertyTemplate(PropertyValueTypeDef type) {
+	public static Property createPropertyTemplate(ValueType type) {
 		Property prop = new Property();
 		prop.setValueType(type);
 		prop.setModelingKind(ModelingKind.TEMPLATE);
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/operation/OperationVariable.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/operation/OperationVariable.java
index 15f6f22..0376c83 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/operation/OperationVariable.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/operation/OperationVariable.java
@@ -1,14 +1,28 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation;
 
 import java.util.Map;
 
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
+import org.eclipse.basyx.submodel.metamodel.api.qualifier.haskind.ModelingKind;
 import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
 import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperationVariable;
 import org.eclipse.basyx.submodel.metamodel.facade.submodelelement.SubmodelElementFacadeFactory;
 import org.eclipse.basyx.submodel.metamodel.map.modeltype.ModelType;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.haskind.HasKind;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElement;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
 import org.eclipse.basyx.vab.model.VABModelMap;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * OperationVariable as described by DAAS document An operation variable is a
@@ -18,6 +32,8 @@
  *
  */
 public class OperationVariable extends VABModelMap<Object> implements IOperationVariable {
+	public static final Logger logger = LoggerFactory.getLogger(OperationVariable.class);
+	
 	public static final String MODELTYPE = "OperationVariable";
 
 	/**
@@ -30,7 +46,7 @@
 		// Add model type
 		putAll(new ModelType(MODELTYPE));
 		
-		put(Property.VALUE, value);
+		setValue(value);
 	}
 
 	public OperationVariable() {
@@ -45,12 +61,44 @@
 	 * @return an OperationVariable object, that behaves like a facade for the given map
 	 */
 	public static OperationVariable createAsFacade(Map<String, Object> obj) {
+		if (obj == null) {
+			return null;
+		}
+		
+		if (!isValid(obj)) {
+			throw new MetamodelConstructionException(OperationVariable.class, obj);	
+		}
+		
 		OperationVariable facade = new OperationVariable();
 		facade.setMap(obj);
 		return facade;
 	}
+	
+	/**
+	 * Check whether all mandatory elements for the metamodel
+	 * exist in a map
+	 * @return true/false
+	 */
+	@SuppressWarnings("unchecked")
+	public static boolean isValid(Map<String, Object> obj) {
+		return obj != null &&
+				obj.containsKey(Property.VALUE) && 
+				SubmodelElement.isValid((Map<String, Object>) obj.get(Property.VALUE));
+	}
 
+	/**
+	 * Sets value of operation variable
+	 *
+	 * @param value
+	 * @throws RuntimeException if modelingkind of the value is not of modelingkind.template
+	 */
+	@SuppressWarnings("unchecked")
 	public void setValue(ISubmodelElement value) {
+		if (value.getModelingKind() != ModelingKind.TEMPLATE) {
+			// TODO: Change with 1.0 Release
+			logger.warn("Modeling kind of Operation variable was wrong and automatically changed to ModelingKind.TEMPLATE");
+			HasKind.createAsFacade((Map<String, Object>) value).setModelingKind(ModelingKind.TEMPLATE);
+		}
 		put(Property.VALUE, value);
 	}
 
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/relationship/AnnotatedRelationshipElement.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/relationship/AnnotatedRelationshipElement.java
new file mode 100644
index 0000000..8e4fb1f
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/relationship/AnnotatedRelationshipElement.java
@@ -0,0 +1,129 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.metamodel.map.submodelelement.relationship;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
+import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IDataElement;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.relationship.IAnnotatedRelationshipElement;
+import org.eclipse.basyx.submodel.metamodel.facade.submodelelement.SubmodelElementFacadeFactory;
+import org.eclipse.basyx.submodel.metamodel.map.modeltype.ModelType;
+
+/**
+ * AnnotatedRelationshipElement as defined in DAAS document <br/>
+ * An annotated relationship element is a relationship element that can be annotated with additional data elements.
+ * 
+ * @author schnicke, conradi
+ *
+ */
+public class AnnotatedRelationshipElement extends RelationshipElement implements IAnnotatedRelationshipElement {
+	public static final String ANNOTATIONS = "annotation";
+	public static final String MODELTYPE = "AnnotatedRelationshipElement";
+
+	public AnnotatedRelationshipElement() {
+		super();
+		// Add model type
+		putAll(new ModelType(MODELTYPE));
+	}
+
+	public AnnotatedRelationshipElement(String idShort, IReference first, IReference second) {
+		super(idShort, first, second);
+		// Add model type
+		putAll(new ModelType(MODELTYPE));
+	}
+
+	public void setAnnotation(Collection<IDataElement> annotations) {
+		put(ANNOTATIONS, annotations);
+	}
+
+	
+	@SuppressWarnings("unchecked")
+	private Collection<IDataElement> getAnnotations() {	
+		Collection<IDataElement> list = new ArrayList<>();
+		Collection<Map<String, Object>> annotations = (Collection<Map<String, Object>>) get(ANNOTATIONS);
+		
+		// If non mandatory element annotations does not exist, return empty list
+		if(annotations == null) {
+			return list;
+		}
+		
+		annotations.stream()
+		.map(m -> SubmodelElementFacadeFactory.createSubmodelElement(m))
+		.filter(e -> e instanceof IDataElement).forEach(e -> list.add((IDataElement)e));
+		
+		return list;
+	}
+
+	
+	@SuppressWarnings("unchecked")
+	@Override
+	public void setValue(Object obj) {
+		if (AnnotatedRelationshipElementValue.isAnnotatedRelationshipElementValue(obj)) {
+			AnnotatedRelationshipElementValue value = AnnotatedRelationshipElementValue.createAsFacade((Map<String, Object>) obj);
+			setValue(value);
+		} else {
+			throw new IllegalArgumentException("Given Object is not an AnnotatedRelationshipElementValue");
+		}
+	}
+
+	/**
+	 * Creates a AnnotatedRelationshipElement object from a map
+	 * 
+	 * @param obj
+	 *            a AnnotatedRelationshipElement object as raw map
+	 * @return a AnnotatedRelationshipElement object, that behaves like a facade for
+	 *         the given map
+	 */
+	public static AnnotatedRelationshipElement createAsFacade(Map<String, Object> obj) {
+		if (obj == null) {
+			return null;
+		}
+
+		if (!isValid(obj)) {
+			throw new MetamodelConstructionException(AnnotatedRelationshipElement.class, obj);
+		}
+
+		AnnotatedRelationshipElement ret = new AnnotatedRelationshipElement();
+		ret.setMap(obj);
+		return ret;
+	}
+
+	/**
+	 * Check whether all mandatory elements for the metamodel exist in a map
+	 * 
+	 * @return true/false
+	 */
+	public static boolean isValid(Map<String, Object> obj) {
+		return RelationshipElement.isValid(obj);
+	}
+
+	public static boolean isAnnotatedRelationshipElement(Map<String, Object> value) {
+		String modelType = ModelType.createAsFacade(value).getName();
+		// Either model type is set or the element type specific attributes are
+		// contained
+		return MODELTYPE.equals(modelType) || (modelType == null && isValid(value));
+	}
+
+	@Override
+	public AnnotatedRelationshipElementValue getValue() {
+		return new AnnotatedRelationshipElementValue(getFirst(), getSecond(), getAnnotations());
+	}
+
+	@Override
+	public void setValue(AnnotatedRelationshipElementValue value) {
+		super.setValue(value);
+		setAnnotation(value.getAnnotations());
+	}
+
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/relationship/AnnotatedRelationshipElementValue.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/relationship/AnnotatedRelationshipElementValue.java
new file mode 100644
index 0000000..b65f2ba
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/relationship/AnnotatedRelationshipElementValue.java
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.metamodel.map.submodelelement.relationship;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Map;
+
+import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IDataElement;
+import org.eclipse.basyx.submodel.metamodel.facade.submodelelement.SubmodelElementFacadeFactory;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
+
+/**
+ * Container class for holding the value of RelationshipElement
+ * 
+ * @author schnicke, conradi
+ *
+ */
+public class AnnotatedRelationshipElementValue extends RelationshipElementValue {
+
+	public AnnotatedRelationshipElementValue(IReference first, IReference second, Collection<IDataElement> annotations) {
+		super(first, second);
+		put(AnnotatedRelationshipElement.ANNOTATIONS, annotations);
+	}
+
+	private AnnotatedRelationshipElementValue() {
+		super();
+	}
+
+	/**
+	 * Creates a AnnotatedRelationshipElementValue object from a map
+	 * 
+	 * @param obj
+	 *            a AnnotatedRelationshipElementValue object as raw map
+	 * @return a AnnotatedRelationshipElementValue object, that behaves like a
+	 *         facade for the given map
+	 */
+	public static AnnotatedRelationshipElementValue createAsFacade(Map<String, Object> obj) {
+		if (obj == null) {
+			return null;
+		}
+
+		AnnotatedRelationshipElementValue facade = new AnnotatedRelationshipElementValue();
+		facade.setMap(obj);
+		return facade;
+	}
+	
+	@SuppressWarnings("unchecked")
+	public static boolean isAnnotatedRelationshipElementValue(Object value) {
+		if(!RelationshipElementValue.isRelationshipElementValue(value)) {
+			return false;
+		} else {
+			Map<String, Object> map = (Map<String, Object>) value;
+			return Reference.isReference(map.get(AnnotatedRelationshipElement.ANNOTATIONS));
+		}
+	}
+	
+	@SuppressWarnings("unchecked")
+	public Collection<IDataElement> getAnnotations() {
+		Collection<IDataElement> list = new ArrayList<>();
+		
+		// Feed all Elements in ANNOTATIONS through the SubmodelElementFacadeFactory
+		// then collect them in a List<IDataElement>
+		((Collection<Map<String, Object>>) get(AnnotatedRelationshipElement.ANNOTATIONS)).stream()
+		.map(m -> SubmodelElementFacadeFactory.createSubmodelElement(m))
+		.filter(e -> e instanceof IDataElement).forEach(e -> list.add((IDataElement)e));
+		
+		return list;
+	}
+
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/relationship/RelationshipElement.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/relationship/RelationshipElement.java
index bb9d5c6..b288e54 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/relationship/RelationshipElement.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/relationship/RelationshipElement.java
@@ -1,7 +1,17 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.metamodel.map.submodelelement.relationship;
 
 import java.util.Map;
 
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
 import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
 import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
 import org.eclipse.basyx.submodel.metamodel.api.submodelelement.relationship.IRelationshipElement;
@@ -29,9 +39,6 @@
 	public RelationshipElement() {
 		// Add model type
 		putAll(new ModelType(MODELTYPE));
-
-		put(FIRST, null);
-		put(SECOND, null);
 	}
 
 	/**
@@ -41,7 +48,7 @@
 	 * @param second
 	 *            Second element in the relationship taking the role of the object.
 	 */
-	public RelationshipElement(Reference first, Reference second) {
+	public RelationshipElement(IReference first, IReference second) {
 		// Add model type
 		putAll(new ModelType(MODELTYPE));
 		
@@ -50,16 +57,50 @@
 	}
 	
 	/**
+	 * Constructor with only mandatory attributes
+	 * @param idShort
+	 * @param first
+	 * @param second
+	 */
+	public RelationshipElement(String idShort, IReference first, IReference second) {
+		this(first, second);
+		setIdShort(idShort);
+	}
+	
+	/**
 	 * Creates a RelationshipElement object from a map
 	 * 
 	 * @param obj a RelationshipElement object as raw map
 	 * @return a RelationshipElement object, that behaves like a facade for the given map
 	 */
 	public static RelationshipElement createAsFacade(Map<String, Object> obj) {
+		if (obj == null) {
+			return null;
+		}
+		
+		if (!isValid(obj)) {
+			throw new MetamodelConstructionException(RelationshipElement.class, obj);
+		}
+		
+		
 		RelationshipElement ret = new RelationshipElement();
 		ret.setMap(obj);
 		return ret;
 	}
+	
+	/**
+	 * Check whether all mandatory elements for the metamodel
+	 * exist in a map
+	 * @return true/false
+	 */
+	@SuppressWarnings("unchecked")
+	public static boolean isValid(Map<String, Object> obj) {
+		return SubmodelElement.isValid(obj) &&
+				obj.containsKey(FIRST) &&
+				obj.containsKey(SECOND) &&
+				Reference.isValid((Map<String, Object>)obj.get(FIRST)) &&
+				Reference.isValid((Map<String, Object>)obj.get(SECOND));
+	}
 
 	/**
 	 * Returns true if the given submodel element map is recognized as a RelationshipElement
@@ -67,7 +108,7 @@
 	public static boolean isRelationshipElement(Map<String, Object> map) {
 		String modelType = ModelType.createAsFacade(map).getName();
 		// Either model type is set or the element type specific attributes are contained
-		return MODELTYPE.equals(modelType) || (map.containsKey(FIRST) && map.containsKey(SECOND));
+		return MODELTYPE.equals(modelType) || (modelType == null && map.containsKey(FIRST) && map.containsKey(SECOND));
 	}
 
 	public void setFirst(IReference first) {
@@ -75,7 +116,6 @@
 		
 	}
 
-	@Override
 	@SuppressWarnings("unchecked")
 	public IReference getFirst() {
 		return Reference.createAsFacade((Map<String, Object>) get(RelationshipElement.FIRST));
@@ -86,7 +126,6 @@
 		
 	}
 
-	@Override
 	@SuppressWarnings("unchecked")
 	public IReference getSecond() {
 		return Reference.createAsFacade((Map<String, Object>) get(RelationshipElement.SECOND));
@@ -96,4 +135,35 @@
 	protected KeyElements getKeyElement() {
 		return KeyElements.RELATIONSHIPELEMENT;
 	}
+
+	@Override
+	public RelationshipElementValue getValue() {
+		return new RelationshipElementValue(getFirst(), getSecond());
+	}
+	
+	@SuppressWarnings("unchecked")
+	@Override
+	public void setValue(Object value) {
+		if(RelationshipElementValue.isRelationshipElementValue(value)) {
+			RelationshipElementValue rev = 
+					RelationshipElementValue.createAsFacade((Map<String, Object>) value);
+			setValue(rev);
+		} else {
+			throw new IllegalArgumentException("Given Object is not an RelationshipElementValue");
+		}
+	}
+
+	@Override
+	public RelationshipElement getLocalCopy() {
+		// Return a shallow copy
+		RelationshipElement copy = new RelationshipElement();
+		copy.putAll(this);
+		return copy;
+	}
+
+	@Override
+	public void setValue(RelationshipElementValue value) {
+		setFirst(value.getFirst());
+		setSecond(value.getSecond());
+	}
 }
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/relationship/RelationshipElementValue.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/relationship/RelationshipElementValue.java
new file mode 100644
index 0000000..952540b
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/relationship/RelationshipElementValue.java
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.metamodel.map.submodelelement.relationship;
+
+import java.util.Map;
+
+import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
+import org.eclipse.basyx.vab.model.VABModelMap;
+
+
+/**
+ * Container class for holding the value of RelationshipElement
+ * 
+ * @author conradi
+ *
+ */
+public class RelationshipElementValue extends VABModelMap<Object> {
+
+	protected RelationshipElementValue() {
+	}
+	
+	public RelationshipElementValue(IReference first, IReference second) {
+		put(RelationshipElement.FIRST, first);
+		put(RelationshipElement.SECOND, second);
+	}
+	
+	/**
+	 * Creates a RelationshipElementValue object from a map
+	 * 
+	 * @param obj a RelationshipElementValue object as raw map
+	 * @return a RelationshipElementValue object, that behaves like a facade for the given map
+	 */
+	public static RelationshipElementValue createAsFacade(Map<String, Object> obj) {
+		if (obj == null) {
+			return null;
+		}
+		
+		RelationshipElementValue facade = new RelationshipElementValue();
+		facade.setMap(obj);
+		return facade;
+	}
+	
+	@SuppressWarnings("unchecked")
+	public static boolean isRelationshipElementValue(Object value) {
+		
+		// Given Object must be a Map
+		if(!(value instanceof Map<?, ?>)) {
+			return false;
+		}
+		
+		Map<String, Object> map = (Map<String, Object>) value;
+		
+		return Reference.isReference(map.get(RelationshipElement.FIRST))
+				&& Reference.isReference(map.get(RelationshipElement.SECOND));
+	}
+	
+	@SuppressWarnings("unchecked")
+	public IReference getFirst() {
+		return Reference.createAsFacade((Map<String, Object>) get(RelationshipElement.FIRST));
+	}
+	
+	@SuppressWarnings("unchecked")
+	public IReference getSecond() {
+		return Reference.createAsFacade((Map<String, Object>) get(RelationshipElement.SECOND));
+	}
+	
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/MetaModelProvider.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/MetaModelProvider.java
deleted file mode 100644
index dd40749..0000000
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/MetaModelProvider.java
+++ /dev/null
@@ -1,43 +0,0 @@
-package org.eclipse.basyx.submodel.restapi;
-
-import java.util.Map;
-
-import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
-
-/**
- * Abstract class that acts as base for each handler of the AAS meta model
- *
- * @author schnicke
- *
- */
-public abstract class MetaModelProvider implements IModelProvider {
-
-	/**
-	 * Unwraps a parameter by retrieving the "value" entry
-	 *
-	 * @param parameter
-	 * @return
-	 */
-	@SuppressWarnings("unchecked")
-	protected Object unwrapParameter(Object parameter) {
-		if (parameter instanceof Map<?, ?>) {
-			Map<String, Object> map = (Map<String, Object>) parameter;
-			// Parameters have a strictly defined order and may not be omitted at all.
-			// Enforcing the structure with valueType is ok, but we should unwrap null values, too.
-			if (map.get("valueType") != null && map.containsKey("value")) {
-				return map.get("value");
-			}
-		}
-		return parameter;
-	}
-
-	/**
-	 * Creates generic exception with Unknown path message
-	 *
-	 * @param path
-	 * @return
-	 */
-	protected RuntimeException getUnknownPathException(String path) {
-		return new RuntimeException("Unknown path: " + path);
-	}
-}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/MultiSubmodelElementProvider.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/MultiSubmodelElementProvider.java
new file mode 100644
index 0000000..9b01728
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/MultiSubmodelElementProvider.java
@@ -0,0 +1,191 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.restapi;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import org.eclipse.basyx.submodel.metamodel.facade.SubmodelElementMapCollectionConverter;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
+import org.eclipse.basyx.vab.exception.provider.MalformedRequestException;
+import org.eclipse.basyx.vab.exception.provider.ProviderException;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+import org.eclipse.basyx.vab.modelprovider.VABPathTools;
+import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
+
+/**
+ * Provider that handles container properties. Container properties can contain other submodel elements.
+ *
+ * @author espen, conradi
+ *
+ */
+public class MultiSubmodelElementProvider implements IModelProvider {
+	// Constants for API-Access
+	public static final String ELEMENTS = "submodelElements";
+	public static final String VALUE = "value";
+
+	// The VAB model provider containing the submodelElements this SubmodelElementProvider is based on
+	// Assumed to be a map that maps idShorts to the submodel elements
+	private IModelProvider modelProvider;
+
+	/**
+	 * Constructor based on a model provider that contains the container property
+	 */
+	public MultiSubmodelElementProvider(IModelProvider provider) {
+		this.modelProvider = provider;
+	}
+
+	/**
+	 * The elements are stored in a map => convert them to a list
+	 */
+	@SuppressWarnings("unchecked")
+	protected Collection<Map<String, Object>> getElementsList() {
+		Object elements = modelProvider.getValue("");
+		Map<String, Map<String, Object>> all = (Map<String, Map<String, Object>>) elements;
+
+		// Feed all ELements through their Providers, in case someting needs to be done to them (e.g. smElemCollections)
+		return all.entrySet().stream().map(e -> (Map<String, Object>) getSingleElement(ELEMENTS + "/" + e.getKey())).collect(Collectors.toList());
+	}
+
+	/**
+	 * Single elements can be directly accessed in maps => return a proxy
+	 */
+	private IModelProvider getElementProxy(String[] pathElements) {
+		String idShort = pathElements[1];
+		return new VABElementProxy(idShort, modelProvider);
+	}
+
+	private Object getSingleElement(String path) {
+		// Build new proxy pointing at sub-property of a submodelelement and forward the
+		// remaininig part of the path to an appropriate provider
+		String[] pathElements = VABPathTools.splitPath(path);
+		String qualifier = pathElements[0];
+		IModelProvider elementProxy = getElementProxy(pathElements);
+
+		if (qualifier.equals(ELEMENTS)) {
+			String subPath = VABPathTools.buildPath(pathElements, 2);
+			return new SubmodelElementProvider(elementProxy).getValue(subPath);
+		} else {
+			throw new MalformedRequestException("Given path '" + path + "' does not start with /submodelElements");
+		}
+	}
+
+	@Override
+	public Object getValue(String path) throws ProviderException {
+		String[] pathElements = VABPathTools.splitPath(path);
+		String qualifier = pathElements[0];
+		
+		if(!qualifier.equals(ELEMENTS)) {
+			// No other qualifier in a submodel element container can be directly accessed
+			throw new MalformedRequestException("Given path '" + path + "' does not start with /submodelElements");
+		}
+		
+		if (pathElements.length == 1) {
+			// returns all elements
+			return getElementsList();
+		} else {
+			// The path requests a single Element
+			return getSingleElement(path);
+		}
+	}
+
+	@Override
+	public void setValue(String path, Object newValue) throws ProviderException {
+		String[] pathElements = VABPathTools.splitPath(path);
+		String qualifier = pathElements[0];
+		if (pathElements.length < 2 || !qualifier.equals(ELEMENTS)) {
+			// only possible to set values in a data elements, currently
+			throw new MalformedRequestException("Given path '" + path + "' is invalid for set");
+		}
+
+		IModelProvider elementProxy = getElementProxy(pathElements);
+		String subPath = VABPathTools.buildPath(pathElements, 2);
+		
+		new SubmodelElementProvider(elementProxy).setValue(subPath, newValue);
+	}
+
+	@Override
+	@SuppressWarnings("unchecked")
+	public void createValue(String path, Object newEntity) throws ProviderException {
+		String[] pathElements = VABPathTools.splitPath(path);
+		String qualifier = pathElements[0];
+		String subPath = VABPathTools.buildPath(pathElements, 2);
+		
+
+		if (!qualifier.equals(ELEMENTS)) {
+			throw new MalformedRequestException("Given path '" + path + "' does not start with /submodelElements");
+		}
+		
+		// Check if the passed element is a SubmodelElementCollection. If yes, the value
+		// of the "value" key needs to be handled
+		if (SubmodelElementCollection.isSubmodelElementCollection((Map<String, Object>) newEntity)) {
+			SubmodelElementCollection smCollection = SubmodelElementCollection.createAsFacade((Map<String, Object>) newEntity);
+			newEntity = SubmodelElementMapCollectionConverter.mapToSmECollection(smCollection);
+		}
+
+		if (pathElements.length == 2) {
+			// It is allowed to overwrite existing properties inside of a submodel
+			try {
+				modelProvider.setValue(pathElements[1], newEntity);
+			} catch (ResourceNotFoundException e) {
+				modelProvider.createValue(pathElements[1], newEntity);
+			}
+		} else {
+			IModelProvider elementProxy = getElementProxy(pathElements);
+			new SubmodelElementProvider(elementProxy).createValue(subPath, newEntity);
+		}
+	}
+
+	@Override
+	public void deleteValue(String path) throws ProviderException {
+		String[] pathElements = VABPathTools.splitPath(path);
+		String qualifier = pathElements[0];
+		String subPath;
+		IModelProvider elementProvider;
+		
+		if (!qualifier.equals(ELEMENTS)) {
+			throw new MalformedRequestException("Given path '" + path + "' does not start with /submodelElements");
+		}
+
+		// If the first Element is a Collection, use its Provider
+		if(pathElements.length > 2) {
+			IModelProvider elementProxy = getElementProxy(pathElements);
+			elementProvider = new SubmodelElementProvider(elementProxy); 
+			subPath = VABPathTools.buildPath(pathElements, 2);
+		} else {
+			elementProvider = modelProvider;
+			subPath = VABPathTools.buildPath(pathElements, 1);
+		}
+
+		// Delete a specific submodel element
+		elementProvider.deleteValue(subPath);
+	}
+
+	@Override
+	public void deleteValue(String path, Object obj) {
+		throw new MalformedRequestException("Delete with a passed argument not allowed");
+	}
+
+	@Override
+	public Object invokeOperation(String path, Object... parameters) throws ProviderException {
+		String[] pathElements = VABPathTools.splitPath(path);
+		String subPath = VABPathTools.buildPath(pathElements, 2);
+
+		String qualifier = pathElements[0];
+		if (!qualifier.equals(ELEMENTS)) {
+			throw new MalformedRequestException("Given path '" + path + "' does not start with /submodelElements");
+		}
+		
+		IModelProvider elementProxy = getElementProxy(pathElements);
+		return new SubmodelElementProvider(elementProxy).invokeOperation(subPath, parameters);
+	}
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/OperationProvider.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/OperationProvider.java
index 024c750..a962722 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/OperationProvider.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/OperationProvider.java
@@ -1,10 +1,31 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.restapi;
 
+import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Map;
+import java.util.UUID;
 
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperationVariable;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElement;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.OperationVariable;
+import org.eclipse.basyx.submodel.restapi.operation.AsyncOperationHandler;
+import org.eclipse.basyx.submodel.restapi.operation.CallbackResponse;
+import org.eclipse.basyx.submodel.restapi.operation.ExecutionState;
+import org.eclipse.basyx.submodel.restapi.operation.InvocationRequest;
+import org.eclipse.basyx.submodel.restapi.operation.InvocationResponse;
 import org.eclipse.basyx.vab.exception.provider.MalformedRequestException;
 import org.eclipse.basyx.vab.exception.provider.ProviderException;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
 import org.eclipse.basyx.vab.modelprovider.VABPathTools;
 import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
 
@@ -14,59 +35,189 @@
  * @author schnicke
  *
  */
-public class OperationProvider extends MetaModelProvider {
+public class OperationProvider implements IModelProvider {
+	public static final String ASYNC = "?async=true";
+	public static final String INVOCATION_LIST = "invocationList";
+	public String operationId;
 
-	IModelProvider modelProvider;
+	private IModelProvider modelProvider;
 
 	public OperationProvider(IModelProvider modelProvider) {
 		this.modelProvider = modelProvider;
+		operationId = getIdShort(modelProvider.getValue(""));
 	}
 
 	@Override
-	public Object getModelPropertyValue(String path) throws ProviderException {
+	public Object getValue(String path) throws ProviderException {
+		String[] splitted = VABPathTools.splitPath(path);
 		if (path.isEmpty()) {
-			return modelProvider.getModelPropertyValue("");
+			return modelProvider.getValue("");
+		} else if (splitted[0].equals(INVOCATION_LIST) && splitted.length == 2) {
+			String requestId = splitted[1];
+			return AsyncOperationHandler.retrieveResult(requestId, operationId);
+			
 		} else {
-			throw new MalformedRequestException("Invalid access path");
+			throw new MalformedRequestException("Get of an Operation supports only empty or /invocationList/{requestId} paths");
 		}
 	}
 
 	@Override
-	public void setModelPropertyValue(String path, Object newValue) throws ProviderException {
-		throw new MalformedRequestException("Invalid access path");
+	public void setValue(String path, Object newValue) throws ProviderException {
+		throw new MalformedRequestException("Set not allowed at path '" + path + "'");
 	}
 
 	@Override
 	public void createValue(String path, Object newEntity) throws ProviderException {
-		throw new MalformedRequestException("Invalid access path");
+		throw new MalformedRequestException("Create not allowed at path '" + path + "'");
 	}
 
 	@Override
 	public void deleteValue(String path) throws ProviderException {
 		// Deletion of operation is handled by parent provider
-		throw new MalformedRequestException("Invalid access path");
+		throw new MalformedRequestException("Delete not allowed at path '" + path + "'");
 	}
 
 	@Override
 	public void deleteValue(String path, Object obj) throws ProviderException {
-		throw new MalformedRequestException("Invalid access path");
+		throw new MalformedRequestException("Delete not allowed at path '" + path + "'");
 	}
 
 	@Override
 	public Object invokeOperation(String path, Object... parameters) throws ProviderException {
-		// Unwrap parameters, if they are wrapped
-		for (int i = 0; i < parameters.length; i++) {
-			parameters[i] = unwrapParameter(parameters[i]);
+		// Fix path
+		boolean async = path.endsWith(ASYNC);
+		// remove the "invoke" from the end of the path
+		path = VABPathTools.stripInvokeFromPath(path);
+
+		// TODO: Only allow wrapped parameters with InvokationRequests
+		Object[] unwrappedParameters;
+		InvocationRequest request = getInvocationRequest(parameters);
+		String requestId;
+		if (request != null) {
+			unwrappedParameters = request.unwrapInputParameters();
+			requestId = request.getRequestId();
+		} else {
+			// => not necessary, if it is only allowed to use InvocationRequests
+			unwrappedParameters = unwrapDirectParameters(parameters);
+			// Generate random request id
+			requestId = UUID.randomUUID().toString();
 		}
 
 		// Invoke /invokable instead of an Operation property if existent
-		Object childElement = modelProvider.getModelPropertyValue(path);
-		if (childElement instanceof Map<?, ?> && ((Map<?, ?>) childElement).containsKey(Operation.INVOKABLE)) {
+		Object childElement = modelProvider.getValue(path);
+		if (Operation.isOperation(childElement)) {
 			path = VABPathTools.concatenatePaths(path, Operation.INVOKABLE);
 		}
+		
+		// Handle async operations
+		if (async) {
+			// Async call? No return value, yet
+			Collection<IOperationVariable> outputVars = copyOutputVariables();
+			IModelProvider provider = new VABElementProxy(path, modelProvider);
 
-		// Forward call to model provider
-		return modelProvider.invokeOperation(path, parameters);
+			// Only necessary as long as invocations without InvokationRequest is allowed
+			if (request != null) {
+				AsyncOperationHandler.invokeAsync(provider, operationId, request, outputVars);
+			} else {
+				AsyncOperationHandler.invokeAsync(provider, operationId, requestId, unwrappedParameters, outputVars,
+						10000);
+			}
+
+			// Request id has to be returned for caller to be able to retrieve result
+			// => Use callback response and leave url empty
+			return new CallbackResponse(requestId, "");
+		}
+
+		// Handle synchronous operations
+		// Forward direct operation call to modelprovider
+		Object directResult = modelProvider.invokeOperation(path, unwrappedParameters);
+		if (request == null) {
+			// Parameters have been passed directly? Directly return the result
+			return directResult;
+		}
+		return createInvocationResponseFromDirectResult(request, directResult);
+	}
+
+	/**
+	 * Directly creates an InvocationResponse from an operation result
+	 */
+	private Object createInvocationResponseFromDirectResult(InvocationRequest request, Object directResult) {
+		// Get SubmodelElement output template
+		Collection<IOperationVariable> outputs = copyOutputVariables();
+		SubmodelElement outputElem = (SubmodelElement) outputs.iterator().next().getValue();
+		// Set result object
+		outputElem.setValue(directResult);
+
+		// Create and return InvokationResponse
+		return new InvocationResponse(request.getRequestId(), new ArrayList<>(), outputs, ExecutionState.COMPLETED);
+	}
+
+	/**
+	 * Extracts an invokation request from a generic parameter array
+	 * 
+	 * @param parameters
+	 * @return
+	 */
+	@SuppressWarnings("unchecked")
+	private InvocationRequest getInvocationRequest(Object[] parameters) {
+		if (parameters.length == 1 && parameters[0] instanceof Map<?, ?>) {
+			Map<String, Object> requestMap = (Map<String, Object>) parameters[0];
+			return InvocationRequest.createAsFacade(requestMap);
+		}
+		return null;
+	}
+	
+	/**
+	 * Gets the (first) output parameter from the underlying object
+	 * 
+	 * @return
+	 */
+	@SuppressWarnings("unchecked")
+	private Collection<IOperationVariable> copyOutputVariables() {
+		Map<String, Object> operationMap = (Map<String, Object>) getValue("");
+		Operation op = Operation.createAsFacade(operationMap);
+		Collection<IOperationVariable> outputs = op.getOutputVariables();
+		Collection<IOperationVariable> outCopy = new ArrayList<>();
+		outputs.stream().forEach(o -> outCopy.add(new OperationVariable(o.getValue().getLocalCopy())));
+		return outCopy;
+	}
+
+	@SuppressWarnings("unchecked")
+	private String getIdShort(Object operation) {
+		if(Operation.isOperation(operation)) {
+			return Operation.createAsFacade((Map<String, Object>) operation).getIdShort();
+		} else {
+			// Should never happen as SubmodelElementProvider.getElementProvider
+			// already checked that it is an Operation, if the Provider is used as intended
+			throw new ProviderException("The Object this OperationProvider is pointing to is not an Operation");
+		}
+	}
+
+	/**
+	 * Unwraps a parameter by retrieving the "value" entry
+	 *
+	 * @param parameter
+	 * @return
+	 */
+	@SuppressWarnings("unchecked")
+	private Object[] unwrapDirectParameters(Object[] parameters) {
+		// Unwrap parameters, if they are wrapped
+		Object[] unwrappedParameters = new Object[parameters.length];
+		for (int i = 0; i < parameters.length; i++) {
+			Object parameter = parameters[i];
+			if (parameter instanceof Map<?, ?>) {
+				Map<String, Object> map = (Map<String, Object>) parameter;
+				// Parameters have a strictly defined order and may not be omitted at all.
+				// Enforcing the structure with valueType is ok, but we should unwrap null
+				// values, too.
+				if (map.get("valueType") != null && map.containsKey("value")) {
+					unwrappedParameters[i] = map.get("value");
+					continue;
+				}
+			}
+			unwrappedParameters[i] = parameter;
+		}
+		return unwrappedParameters;
 	}
 
 }
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/PropertyProvider.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/PropertyProvider.java
index 91b2030..846fe85 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/PropertyProvider.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/PropertyProvider.java
@@ -1,10 +1,18 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.restapi;
 
-import java.util.HashMap;
 import java.util.Map;
 
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetypedef.PropertyValueTypeDefHelper;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueTypeHelper;
 import org.eclipse.basyx.vab.exception.provider.MalformedRequestException;
 import org.eclipse.basyx.vab.exception.provider.ProviderException;
 import org.eclipse.basyx.vab.modelprovider.VABPathTools;
@@ -16,7 +24,7 @@
  * @author schnicke
  *
  */
-public class PropertyProvider extends MetaModelProvider {
+public class PropertyProvider implements IModelProvider {
 
 	private IModelProvider proxy;
 
@@ -26,64 +34,54 @@
 
 	@SuppressWarnings("unchecked")
 	@Override
-	public Object getModelPropertyValue(String path) throws ProviderException {
+	public Object getValue(String path) throws ProviderException {
 		path = VABPathTools.stripSlashes(path);
 
 		// Handle "/value" path
 		if (path.equals(Property.VALUE)) {
-			// Build map containing value & valueType
-			Map<String, Object> p = (Map<String, Object>) proxy.getModelPropertyValue("");
-			Map<String, Object> ret = new HashMap<>();
-			Object o = p.get(Property.VALUE);
+			// return value
+			Map<String, Object> p = (Map<String, Object>) proxy.getValue("");
+			return p.get(Property.VALUE);
 
-			// Wrap return value in map describing it
-			ret.put(Property.VALUE, o);
-			ret.put(Property.VALUEID, p.get(Property.VALUEID));
-			if (p.containsKey(Property.VALUETYPE)) {
-				ret.put(Property.VALUETYPE, p.get(Property.VALUETYPE));
-			} else {
-				ret.put(Property.VALUETYPE, PropertyValueTypeDefHelper.getTypeWrapperFromObject(o));
-			}
-			return ret;
 		} else if (path.isEmpty()) {
 			// Handle "" path by returning complete property
-			return proxy.getModelPropertyValue("");
+			return proxy.getValue("");
 		} else {
-			throw getUnknownPathException(path);
+			throw new MalformedRequestException("Unknown path: " + path);
 		}
 	}
 
 	@Override
-	public void setModelPropertyValue(String path, Object newValue) throws ProviderException {
+	public void setValue(String path, Object newValue) throws ProviderException {
 		path = VABPathTools.stripSlashes(path);
 		// Only handle "/value" paths
 		if (path.equals(Property.VALUE)) {
 			// Set value and type
-			proxy.setModelPropertyValue(Property.VALUE, newValue);
-			proxy.setModelPropertyValue(Property.VALUETYPE, PropertyValueTypeDefHelper.getTypeWrapperFromObject(newValue));
+			proxy.setValue(Property.VALUE, newValue);
+			proxy.setValue(Property.VALUETYPE, ValueTypeHelper.getType(newValue).toString());
 		} else {
-			throw new MalformedRequestException("Invalid access path");
+			throw new MalformedRequestException("Given Set path '" + path + "' does not end in /value");
 		}
 	}
 
 	@Override
 	public void createValue(String path, Object newEntity) throws ProviderException {
-		throw new MalformedRequestException("Invalid access path");
+		throw new MalformedRequestException("Create not allowed at path '" + path + "'");
 	}
 
 	@Override
 	public void deleteValue(String path) throws ProviderException {
-		throw new MalformedRequestException("Invalid access path");
+		throw new MalformedRequestException("Delete not allowed at path '" + path + "'");
 	}
 
 	@Override
 	public void deleteValue(String path, Object obj) throws ProviderException {
-		throw new MalformedRequestException("Invalid access path");
+		throw new MalformedRequestException("Delete not allowed at path '" + path + "'");
 	}
 
 	@Override
 	public Object invokeOperation(String path, Object... parameter) throws ProviderException {
-		throw new MalformedRequestException("Invalid access path");
+		throw new MalformedRequestException("Invoke not allowed at path '" + path + "'");
 	}
 
 }
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/SubModelProvider.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/SubModelProvider.java
deleted file mode 100644
index 97ebf4f..0000000
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/SubModelProvider.java
+++ /dev/null
@@ -1,224 +0,0 @@
-package org.eclipse.basyx.submodel.restapi;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElement;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.submodel.restapi.api.ISubmodelAPI;
-import org.eclipse.basyx.submodel.restapi.vab.VABSubmodelAPI;
-import org.eclipse.basyx.vab.exception.provider.MalformedRequestException;
-import org.eclipse.basyx.vab.exception.provider.ProviderException;
-import org.eclipse.basyx.vab.modelprovider.VABPathTools;
-import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
-import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaProvider;
-
-/**
- * Additional VAB provider specific for providing submodels together
- * with other SDKs by implementing the submodel API.
- *
- * The VAB provides generic models without considering high-level information.
- * For example, Operation submodel elements are realized as a Map. The function
- * is contained and can be accessed at /operations/opId/invokable. Therefore
- * invoking the Operation directly at /operations/opId/ attempts to invoke the
- * Map, which does not have any effect for the VABModelProvider.
- *
- * This provider maps these requests to the VAB primitives to generate the
- * desired behavior as it is described in the BaSys documentation.
- *
- * @author espen, schnicke
- *
- */
-public class SubModelProvider extends MetaModelProvider {
-
-	ISubmodelAPI submodelAPI;
-
-	/**
-	 * Default constructor - based on an empty submodel with a lambda provider
-	 */
-	public SubModelProvider() {
-		this(new SubModel());
-	}
-
-	/**
-	 * Creates a SubmodelProvider based on the VAB API, wrapping the passed provider
-	 * 
-	 * @param provider
-	 *            to be wrapped by submodel API
-	 */
-	public SubModelProvider(IModelProvider provider) {
-		submodelAPI = new VABSubmodelAPI(provider);
-	}
-
-	/**
-	 * Creates a SubModelProvider based on a lambda provider and a given model
-	 */
-	public SubModelProvider(SubModel model) {
-		submodelAPI = new VABSubmodelAPI(new VABLambdaProvider(model));
-	}
-
-	/**
-	 * Creates a SubModelProvider based on a given ISubmodelAPI.
-	 */
-	public SubModelProvider(ISubmodelAPI submodelAPI) {
-		this.submodelAPI = submodelAPI;
-	}
-
-	/**
-	 * Strips submodel prefix if it exists
-	 *
-	 * @param path
-	 * @return
-	 */
-	private String removeSubmodelPrefix(String path) {
-		path = VABPathTools.stripSlashes(path);
-		if (path.startsWith("submodel/")) {
-			path = path.replaceFirst("submodel/", "");
-		} else if (path.equals("submodel")) {
-			path = "";
-		}
-		path = VABPathTools.stripSlashes(path);
-		return path;
-	}
-
-	@Override
-	public Object getModelPropertyValue(String path) throws ProviderException {
-		VABPathTools.checkPathForNull(path);
-		path = removeSubmodelPrefix(path);
-		if (path.isEmpty()) {
-			return submodelAPI.getSubmodel();
-		} else {
-			String[] splitted = VABPathTools.splitPath(path);
-			String qualifier = splitted[0];
-			if (splitted.length == 1 && isQualifier(splitted[0])) { // Request for either properties, operations or submodelElements
-				switch (qualifier) {
-				case SubmodelElementProvider.ELEMENTS:
-					return submodelAPI.getElements();
-				case SubmodelElementProvider.OPERATIONS:
-					return submodelAPI.getOperations();
-				case SubmodelElementProvider.PROPERTIES:
-					return submodelAPI.getProperties();
-				}
-			} else if (splitted.length >= 2 && isQualifier(splitted[0])) { // Request for element with specific idShort
-				String idShort = splitted[1];
-				if (splitted.length == 2) {
-					return submodelAPI.getSubmodelElement(idShort);
-				} else if (isPropertyValuePath(splitted)) { // Request for the value of an property
-					return submodelAPI.getPropertyValue(idShort);
-				} else if (isSubmodelElementListPath(splitted)) {
-					// Create list from array and wrap it in ArrayList to ensure modifiability
-					List<String> idShorts = getIdShorts(splitted);
-					
-					if (endsWithValue(splitted)) {
-						return submodelAPI.getNestedPropertyValue(idShorts);
-					} else {
-						return submodelAPI.getNestedSubmodelElement(idShorts);
-					}
-				}
-			}
-		}
-		throw new MalformedRequestException("Unknown path " + path + " was requested");
-	}
-
-	private List<String> getIdShorts(String[] splitted) {
-		// Create list from array and wrap it in ArrayList to ensure modifiability
-		List<String> idShorts = new ArrayList<>(Arrays.asList(splitted));
-
-		// Drop inital "submodels"
-		idShorts.remove(0);
-
-		// If value is contained in path, remove it
-		if (splitted[splitted.length - 1].equals(Property.VALUE)) {
-			idShorts.remove(idShorts.size() - 1);
-		}
-		return idShorts;
-	}
-
-	private boolean isPropertyValuePath(String[] splitted) {
-		return splitted.length == 3 && splitted[0].equals(SubmodelElementProvider.PROPERTIES) && endsWithValue(splitted);
-	}
-
-	private boolean endsWithValue(String[] splitted) {
-		return splitted[splitted.length - 1].equals(Property.VALUE);
-	}
-
-	private boolean isSubmodelElementListPath(String[] splitted) {
-		return splitted.length > 2 && splitted[0].equals(SubmodelElementProvider.ELEMENTS);
-	}
-
-	@Override
-	public void setModelPropertyValue(String path, Object newValue) throws ProviderException {
-		path = removeSubmodelPrefix(path);
-		if (path.isEmpty()) {
-			throw new MalformedRequestException("Set on \"submodel\" not supported");
-		} else {
-			String[] splitted = VABPathTools.splitPath(path);
-			if (isPropertyValuePath(splitted)) {
-				String idShort = splitted[1];
-				submodelAPI.updateProperty(idShort, newValue);
-			} else {
-				throw new MalformedRequestException("Update on path " + path + " not supported");
-			}
-		}
-	}
-
-	@SuppressWarnings("unchecked")
-	@Override
-	public void createValue(String path, Object newEntity) throws ProviderException {
-		path = removeSubmodelPrefix(path);
-		if (path.isEmpty()) {
-			// not possible to overwrite existing submodels
-			throw new MalformedRequestException("Invalid access");
-		} else {
-			submodelAPI.addSubmodelElement(SubmodelElement.createAsFacade((Map<String, Object>) newEntity));
-		}
-	}
-
-	@Override
-	public void deleteValue(String path) throws ProviderException {
-		path = removeSubmodelPrefix(path);
-		if (!path.isEmpty()) {
-			String[] splitted = VABPathTools.splitPath(path);
-			if (splitted.length == 2 && isQualifier(splitted[0])) {
-				String idShort = splitted[1];
-				submodelAPI.deleteSubmodelElement(idShort);
-			} else {
-				throw new MalformedRequestException("Path " + path + " not supported for delete");
-			}
-		} else {
-			throw new MalformedRequestException("Path \"submodel\" not supported for delete");
-		}
-	}
-
-	private boolean isQualifier(String str) {
-		return str.equals(SubmodelElementProvider.ELEMENTS) || str.equals(SubmodelElementProvider.OPERATIONS) || str.equals(SubmodelElementProvider.PROPERTIES);
-	}
-
-	@Override
-	public void deleteValue(String path, Object obj) throws ProviderException {
-		throw new MalformedRequestException("Delete with a passed argument not allowed");
-	}
-
-	@Override
-	public Object invokeOperation(String path, Object... parameters) throws ProviderException {
-		path = removeSubmodelPrefix(path);
-		if (path.isEmpty()) {
-			throw new MalformedRequestException("Invalid access");
-		} else {
-			String[] splitted = VABPathTools.splitPath(path);
-			if (splitted.length == 2 && splitted[0].equals(SubmodelElementProvider.OPERATIONS)) {
-				String idShort = splitted[1];
-				return submodelAPI.invokeOperation(idShort, parameters);
-			} else {
-				throw new MalformedRequestException("Unknown path " + path);
-			}
-		}
-	}
-
-	protected void setAPI(ISubmodelAPI api) {
-		this.submodelAPI = api;
-	}
-}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/SubmodelElementCollectionProvider.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/SubmodelElementCollectionProvider.java
index b9da328..19f66b7 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/SubmodelElementCollectionProvider.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/SubmodelElementCollectionProvider.java
@@ -1,24 +1,31 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.restapi;
 
-import java.util.Collection;
 import java.util.Map;
 
-import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
-import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.facade.SubmodelElementMapCollectionConverter;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
 import org.eclipse.basyx.vab.exception.provider.MalformedRequestException;
 import org.eclipse.basyx.vab.exception.provider.ProviderException;
 import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
 import org.eclipse.basyx.vab.modelprovider.VABPathTools;
 import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
-import org.eclipse.basyx.vab.modelprovider.map.VABMapProvider;
 
 /**
  * Handles access to SubmodelElementCollections.
  *
- * @author espen
+ * @author espen, conradi
  */
-public class SubmodelElementCollectionProvider extends MetaModelProvider {
+public class SubmodelElementCollectionProvider implements IModelProvider {
 
 	private IModelProvider proxy;
 
@@ -27,60 +34,62 @@
 	}
 
 	/**
-	 * Single list elements cannot be directly accessed => resolve it and return a provider
-	 * for the single element
+	 * Get a single smElement for a given idShort and return a provider for it
 	 */
-	@SuppressWarnings("unchecked")
 	protected IModelProvider getElementProvider(String idShort) {
-		// Not possible to access single list elements via provider => copy it and wrap it into the
-		// correspondent ElementProvider
 
-		// Resolve the list and return a wrapper provider for the queried element
-		Collection<Map<String, Object>> list = (Collection<Map<String, Object>>) proxy
-				.getModelPropertyValue(Property.VALUE);
+		// The "value" before the id is needed by the providers lower down in order to handle collections correctly
+		// The paths then look like e.g. "submodelElements/collectionID/value/propertyID"
+		IModelProvider defaultProvider = new VABElementProxy(
+				VABPathTools.concatenatePaths(MultiSubmodelElementProvider.VALUE, idShort), proxy);
 
-		// Wrap the resolved property with idShort into a SubmodelElementProvider and return that provider
-		Map<String, Object> element = findElementInList(idShort, list);
-		IModelProvider defaultProvider = new VABMapProvider(element);
-		return SubmodelElementProvider.getElementProvider(element, defaultProvider);
+		// Wrap the property with idShort into a SubmodelElementProvider and return that provider
+		return new SubmodelElementProvider(defaultProvider);
 	}
 
-	private Map<String, Object> findElementInList(String idShort, Collection<Map<String, Object>> list) {
-		for (Map<String, Object> elem : list) {
-			if (idShort.equals(Referable.createAsFacade(elem, KeyElements.SUBMODELELEMENT).getIdShort())) {
-				return elem;
-			}
-		}
-		throw new ResourceNotFoundException("The element \"" + idShort + "\" could not be found");
-	}
-
+	@SuppressWarnings("unchecked")
 	@Override
-	public Object getModelPropertyValue(String path) throws ProviderException {
+	public Object getValue(String path) throws ProviderException {
 		path = VABPathTools.stripSlashes(path);
 		String[] pathElements = VABPathTools.splitPath(path);
 
-		if (path.isEmpty() || path.equals(Property.VALUE)) {
-			return proxy.getModelPropertyValue(path);
+		if (path.isEmpty()) {
+			// Convert the internally used Map to a Collection before returning the smECollection
+			Map<String, Object> map = (Map<String, Object>) proxy.getValue(path);
+			SubmodelElementCollection smElemColl = SubmodelElementCollection.createAsFacade(map);
+			return SubmodelElementMapCollectionConverter.smElementToMap(smElemColl);
+		} else if(path.equals(MultiSubmodelElementProvider.VALUE)) {
+			// Return only a Collection of Elements. Not the internally used Map.
+			return SubmodelElementMapCollectionConverter.convertIDMapToCollection(proxy.getValue(path));
 		} else {
 			// Directly access an element inside of the collection
 			String idShort = pathElements[0];
 			String subPath = VABPathTools.buildPath(pathElements, 1);
-			return getElementProvider(idShort).getModelPropertyValue(subPath);
+			
+			return getElementProvider(idShort).getValue(subPath);
 		}
 	}
 
+	@SuppressWarnings("unchecked")
 	@Override
-	public void setModelPropertyValue(String path, Object newValue) throws ProviderException {
+	public void setValue(String path, Object newValue) throws ProviderException {
 		path = VABPathTools.stripSlashes(path);
 		String[] pathElements = VABPathTools.splitPath(path);
 
-		if (path.isEmpty() || path.equals(Property.VALUE)) {
-			proxy.setModelPropertyValue(path, newValue);
+		if (path.isEmpty()) {
+			// Convert the Collection of Elements to the internally used Map
+			Map<String, Object> value =
+					SubmodelElementMapCollectionConverter.mapToSmECollection((Map<String, Object>) newValue);
+			proxy.setValue(path, value);
+		} else if(path.equals(MultiSubmodelElementProvider.VALUE)) {
+			// Convert the Collection of Elements to the internally used Map
+			Map<String, Object> value = SubmodelElementMapCollectionConverter.convertCollectionToIDMap(newValue);
+			proxy.setValue(path, value);
 		} else {
 			// Directly access an element inside of the collection
 			String idShort = pathElements[0];
 			String subPath = VABPathTools.buildPath(pathElements, 1);
-			getElementProvider(idShort).setModelPropertyValue(subPath, newValue);
+			getElementProvider(idShort).setValue(subPath, newValue);
 		}
 	}
 
@@ -89,8 +98,14 @@
 		path = VABPathTools.stripSlashes(path);
 		String[] pathElements = VABPathTools.splitPath(path);
 
-		if (path.isEmpty() || path.equals(Property.VALUE)) {
-			proxy.createValue(path, newEntity);
+		if (pathElements.length == 1) {
+			String valuePath = VABPathTools.concatenatePaths(MultiSubmodelElementProvider.VALUE, path);
+			// It is allowed to overwrite existing properties inside of collections
+			try {
+				proxy.setValue(valuePath, newEntity);
+			} catch (ResourceNotFoundException e) {
+				proxy.createValue(valuePath, newEntity);
+			}
 		} else {
 			// Directly access an element inside of the collection
 			String idShort = pathElements[0];
@@ -101,22 +116,28 @@
 
 	@Override
 	public void deleteValue(String path) throws ProviderException {
-		throw new MalformedRequestException("Invalid access path");
+		path = VABPathTools.stripSlashes(path);
+		String[] pathElements = VABPathTools.splitPath(path);
+		
+		// "value" is a keyword and can not be used as the ID of an Element
+		if (path.isEmpty() || path.equals(MultiSubmodelElementProvider.VALUE)) {
+			throw new MalformedRequestException("Path must not be empty or /value");
+		} else {
+			// If Path contains only one Element, use the proxy directly
+			if(pathElements.length == 1) {
+				proxy.deleteValue(VABPathTools.concatenatePaths(MultiSubmodelElementProvider.VALUE, path));
+			} else {
+				// If Path contains more Elements, get the Provider for the first Element in Path
+				String idShort = pathElements[0];
+				String subPath = VABPathTools.buildPath(pathElements, 1);
+				getElementProvider(idShort).deleteValue(subPath);
+			}
+		}
 	}
 
 	@Override
 	public void deleteValue(String path, Object obj) throws ProviderException {
-		path = VABPathTools.stripSlashes(path);
-		String[] pathElements = VABPathTools.splitPath(path);
-
-		if (path.isEmpty() || path.equals(Property.VALUE)) {
-			proxy.deleteValue(path, obj);
-		} else {
-			// Directly access an element inside of the collection
-			String idShort = pathElements[0];
-			String subPath = VABPathTools.buildPath(pathElements, 1);
-			getElementProvider(idShort).deleteValue(subPath, obj);
-		}
+		throw new MalformedRequestException("Delete with a passed argument not allowed");
 	}
 
 	@Override
@@ -124,8 +145,8 @@
 		path = VABPathTools.stripSlashes(path);
 		String[] pathElements = VABPathTools.splitPath(path);
 
-		if (path.isEmpty() || path.equals(Property.VALUE)) {
-			throw new MalformedRequestException("Invalid access path");
+		if (path.isEmpty() || path.equals(MultiSubmodelElementProvider.VALUE)) {
+			throw new MalformedRequestException("Path must not be empty or /value");
 		} else {
 			// Directly access an element inside of the collection
 			String idShort = pathElements[0];
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/SubmodelElementProvider.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/SubmodelElementProvider.java
index ed7bc85..d441a41 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/SubmodelElementProvider.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/SubmodelElementProvider.java
@@ -1,240 +1,154 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.restapi;
 
-import java.util.Collection;
 import java.util.Map;
-import java.util.stream.Collectors;
 
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.facade.submodelelement.SubmodelElementFacadeFactory;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.DataElement;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation;
 import org.eclipse.basyx.vab.exception.provider.MalformedRequestException;
 import org.eclipse.basyx.vab.exception.provider.ProviderException;
-import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
 import org.eclipse.basyx.vab.modelprovider.VABPathTools;
 import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
 
 /**
- * Provider that handles container properties. Container properties can contain other submodel elements.
+ * Handles a SubmodelElement according to AAS meta model
  *
- * @author espen
+ * @author schnicke, conradi
  *
  */
-public class SubmodelElementProvider extends MetaModelProvider {
-	// Constants for API-Access
-	public static final String ELEMENTS = "submodelElements";
-	public static final String PROPERTIES = "properties";
-	public static final String OPERATIONS = "operations";
+public class SubmodelElementProvider implements IModelProvider {
 
-	// The VAB model provider containing the submodelElements this SubmodelElementProvider is based on
-	// Assumed to be a map that maps idShorts to the submodel elements
-	private IModelProvider modelProvider;
-
-	/**
-	 * Constructor based on a model provider that contains the container property
-	 */
-	public SubmodelElementProvider(IModelProvider provider) {
-		this.modelProvider = provider;
-	}
-
-	/**
-	 * Method for wrapping a generic Map-SubmodelElement in a concrete provider
-	 * 
-	 * @param element      The data with the submodel element
-	 * @param genericProxy A generic element provider for the element
-	 * @return A specific submodel element model provider (e.g. OperationProvider)
-	 */
-	public static IModelProvider getElementProvider(Map<String, Object> element, IModelProvider genericProxy) {
-		if (DataElement.isDataElement(element)) {
-			return new PropertyProvider(genericProxy);
-		} else if (Operation.isOperation(element)) {
-			return new OperationProvider(genericProxy);
-		} else if (SubmodelElementCollection.isSubmodelElementCollection(element)) {
-			return new SubmodelElementCollectionProvider(genericProxy);
-		} else {
-			return genericProxy;
-		}
-	}
-
-	/**
-	 * The elements are stored in a map => convert them to a list
-	 */
-	@SuppressWarnings("unchecked")
-	protected Collection<Map<String, Object>> getElementsList() {
-		Object elements = modelProvider.getModelPropertyValue("");
-		Map<String, Map<String, Object>> all = (Map<String, Map<String, Object>>) elements;
-		return all.values().stream().collect(Collectors.toList());
-	}
+	private IModelProvider proxy;
 	
-	private Collection<Map<String, Object>> getPropertyList() {
-		Collection<Map<String, Object>> all = getElementsList();
-		// Property detection => has ("value" but not "ordered") or ("min" and "max")
-		return all.stream().filter(Property::isProperty).collect(Collectors.toList());
-	}
+	// Flag used to indicate whether a specialized ElementProvider is used
+	private boolean specializedProvider = false;
 
-	private Collection<Map<String, Object>> getOperationList() {
-		Collection<Map<String, Object>> all = getElementsList();
-		return all.stream().filter(Operation::isOperation).collect(Collectors.toList());
+	public SubmodelElementProvider(IModelProvider proxy) {
+		IModelProvider unchangedProxy = proxy;
+		this.proxy = getElementProvider(proxy);
+		// if the returned element provider is the same, no specialized provider exists
+		specializedProvider = unchangedProxy != this.proxy;
 	}
 
 	/**
-	 * Handles first-level access on submodel elements (e.g. /properties/)
+	 * Used to find out if an Element needs a specialized Provider (Collection, Operation)
+	 * 
+	 * @param proxy the Provider given from above
+	 * @return either the unchanged Provider or the Provider nested into a specialized ElementProvider
 	 */
-	private Object handleQualifierGet(String qualifier, String path) {
-		if (qualifier.equals(PROPERTIES)) {
-			return getPropertyList();
-		} else if (qualifier.equals(OPERATIONS)) {
-			return getOperationList();
-		} else if (qualifier.equals(ELEMENTS)) {
-			// returns all elements
-			return getElementsList();
-		} else {
-			// No other qualifier in a submodel element container can be directly accessed
-			throw getUnknownPathException(path);
-		}
-	}
-
-	/**
-	 * Single elements can be directly accessed in maps => return a proxy
-	 */
-	private IModelProvider getElementProxy(String[] pathElements) {
-		String idShort = pathElements[1];
-		return new VABElementProxy(idShort, modelProvider);
-	}
-
 	@SuppressWarnings("unchecked")
-	private Object handleDetailGet(String path) {
-		// Build new proxy pointing at sub-property of a submodelelement and forward the
-		// remaininig part of the path to an appropriate provider
-		String[] pathElements = VABPathTools.splitPath(path);
-		String qualifier = pathElements[0];
-		String subPath = VABPathTools.buildPath(pathElements, 2);
-		IModelProvider elementProxy = getElementProxy(pathElements);
-		Map<String, Object> element = (Map<String, Object>) elementProxy.getModelPropertyValue("");
-
-		if (pathElements.length == 2) {
-			return element;
-		}
-
-		switch (qualifier) {
-			case (ELEMENTS):
-				return getElementProvider(element, elementProxy).getModelPropertyValue(subPath);
-			case (PROPERTIES):
-				return new PropertyProvider(elementProxy).getModelPropertyValue(subPath);
-			case (OPERATIONS):
-				return new OperationProvider(elementProxy).getModelPropertyValue(subPath);
-			default:
-				throw new MalformedRequestException("Invalid access");
-		}
-	}
-
-	@Override
-	public Object getModelPropertyValue(String path) throws ProviderException {
-		String[] pathElements = VABPathTools.splitPath(path);
-		String qualifier = pathElements[0];
-		if (pathElements.length == 1) {
-			return handleQualifierGet(qualifier, path);
+	public static IModelProvider getElementProvider(IModelProvider proxy) {
+		Map<String, Object> elementMap = (Map<String, Object>) proxy.getValue("");
+		if(Operation.isOperation(elementMap)) {
+			return new OperationProvider(proxy);
+		} else if (SubmodelElementCollection.isSubmodelElementCollection(elementMap)) {
+			return new SubmodelElementCollectionProvider(proxy);
+		} else if(Property.isProperty(elementMap)) {
+			return new PropertyProvider(proxy);
 		} else {
-			return handleDetailGet(path);
+			return proxy;
 		}
 	}
 
 	@SuppressWarnings("unchecked")
 	@Override
-	public void setModelPropertyValue(String path, Object newValue) throws ProviderException {
-		String[] pathElements = VABPathTools.splitPath(path);
-		String qualifier = pathElements[0];
-		if (pathElements.length < 2 || (!qualifier.equals(PROPERTIES) && !qualifier.equals(ELEMENTS))) {
-			// only possible to set values in a data elements, currently
-			throw new MalformedRequestException("Invalid access");
-		}
+	public Object getValue(String path) throws ProviderException {
+		path = VABPathTools.stripSlashes(path);
 
-		IModelProvider elementProxy = getElementProxy(pathElements);
-		Map<String, Object> element = (Map<String, Object>) elementProxy.getModelPropertyValue("");
-		newValue = unwrapParameter(newValue);
-		if (Operation.isOperation(element)) {
-			throw new MalformedRequestException("Invalid access");
-		} else if (Property.isProperty(element)) {
-			String subPath = VABPathTools.buildPath(pathElements, 2);
-			new PropertyProvider(elementProxy).setModelPropertyValue(subPath, newValue);
+		if (path.equals(MultiSubmodelElementProvider.VALUE)) {
+			// Handle "/value" path
+			// return value
+			
+			if(specializedProvider) {
+				return proxy.getValue(path);
+			}
+			
+			Map<String, Object> elementMap = (Map<String, Object>) proxy.getValue("");
+			
+			ISubmodelElement element = SubmodelElementFacadeFactory.createSubmodelElement(elementMap);
+			
+			try {
+				return element.getValue();
+			} catch (UnsupportedOperationException e) {
+				// e.g. an Operation
+				throw new MalformedRequestException("The requested Element '" + element.getIdShort() + "' has no value.");
+			}
 		} else {
-			// API for other elements not specified, yet => let modelprovider resolve request
-			String subPath = VABPathTools.buildPath(pathElements, 2);
-			elementProxy.setModelPropertyValue(subPath, newValue);
+			// Path has more Elements -> pass it to Provider below
+			return proxy.getValue(path);
+		}
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public void setValue(String path, Object newValue) throws ProviderException {
+		path = VABPathTools.stripSlashes(path);
+		
+		if(!path.endsWith(MultiSubmodelElementProvider.VALUE)) {
+			throw new MalformedRequestException("The given path '" + path + "' does not end in /value.");
+		}
+		
+		if (!specializedProvider && path.equals(MultiSubmodelElementProvider.VALUE)) {
+			// Path is only "value" and no specialized Provider has to be used -> update the Element of this Provider
+			Map<String, Object> elementMap = (Map<String, Object>) proxy.getValue("");
+			
+			ISubmodelElement element = SubmodelElementFacadeFactory.createSubmodelElement(elementMap);
+			
+			try {
+				element.setValue(newValue);				
+			} catch (IllegalArgumentException e) {
+				throw new MalformedRequestException("The given Value was not valid for Element '" + path + "'");
+			}
+			
+			proxy.setValue("", element);
+			
+		} else {
+			// Path has more Elements -> pass it to Provider below
+			proxy.setValue(path, newValue);
 		}
 	}
 
 	@Override
 	public void createValue(String path, Object newEntity) throws ProviderException {
-		if (path.equals(PROPERTIES) || path.equals(OPERATIONS) || path.equals(ELEMENTS)) {
-			createSubmodelElement(newEntity);
+		if(!specializedProvider) {
+			// In a regular SubmodelElement nothing can be created
+			throw new MalformedRequestException("Creating a new Element is not allowed at '" + path + "'");
 		} else {
-			String[] pathElements = VABPathTools.splitPath(path);
-			IModelProvider elementProxy = getElementProxy(pathElements);
-			String subPath = VABPathTools.buildPath(pathElements, 2);
-			// API for other elements not specified, yet => let modelprovider resolve request
-			elementProxy.createValue(subPath, newEntity);
+			// If a specialized Provider is used, pass it down
+			proxy.createValue(path, newEntity);
 		}
 	}
 
 	@Override
 	public void deleteValue(String path) throws ProviderException {
-		String[] pathElements = VABPathTools.splitPath(path);
-		if (pathElements.length < 2) {
-			// only possible to directly delete elements with this deletion type
-			throw new MalformedRequestException("Invalid access");
-		}
-
-		String qualifier = pathElements[0];
-		String idShort = pathElements[1];
-		if (qualifier.equals(PROPERTIES) || qualifier.equals(OPERATIONS) || qualifier.equals(ELEMENTS)) {
-			// Delete a specific submodel element
-			modelProvider.deleteValue(idShort);
+		if(!specializedProvider) {
+			// From a regular SubmodelElement nothing can be deleted
+			throw new MalformedRequestException("Deleting the Element '" + path + "' is not allowed");
 		} else {
-			throw new MalformedRequestException("Unknown access path " + path);
+			// If a specialized Provider is used, pass it down
+			proxy.deleteValue(path);
 		}
 	}
 
 	@Override
-	public void deleteValue(String path, Object obj) {
-		String[] pathElements = VABPathTools.splitPath(path);
-		String qualifier = pathElements[0];
-		if (!qualifier.equals(ELEMENTS) && !qualifier.equals(PROPERTIES)) {
-			// only possible to delete values from data elements (or in collections)
-			throw new MalformedRequestException("Invalid access");
-		}
-		IModelProvider elementProxy = getElementProxy(pathElements);
-		String subPath = VABPathTools.buildPath(pathElements, 2);
-		elementProxy.deleteValue(subPath, obj);
+	public void deleteValue(String path, Object obj) throws ProviderException {
+		throw new MalformedRequestException("Delete with a passed argument not allowed");
 	}
 
-	@SuppressWarnings("unchecked")
 	@Override
-	public Object invokeOperation(String path, Object... parameters) throws ProviderException {
-		String[] pathElements = VABPathTools.splitPath(path);
-		String qualifier = pathElements[0];
-		if (pathElements.length < 2 || (!qualifier.equals(OPERATIONS) && !qualifier.equals(ELEMENTS))) {
-			// only possible to invoke operations
-			throw new MalformedRequestException("Invalid access");
-		}
-
-		IModelProvider elementProxy = getElementProxy(pathElements);
-		Map<String, Object> element = (Map<String, Object>) elementProxy.getModelPropertyValue("");
-
-		if (!Operation.isOperation(element)) {
-			// only possible to invoke operations
-			throw new MalformedRequestException("Invalid access");
-		}
-
-		String subPath = VABPathTools.buildPath(pathElements, 2);
-		return new OperationProvider(elementProxy).invokeOperation(subPath, parameters);
+	public Object invokeOperation(String path, Object... parameter) throws ProviderException {
+		return proxy.invokeOperation(path, parameter);		
 	}
 
-	@SuppressWarnings("unchecked")
-	private void createSubmodelElement(Object newEntity) {
-		// Create Operation or DataElement in a map
-		String id = SubmodelElement.createAsFacade((Map<String, Object>) newEntity).getIdShort();
-		modelProvider.createValue(id, newEntity);
-	}
 }
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/SubmodelProvider.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/SubmodelProvider.java
new file mode 100644
index 0000000..3dcb31b
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/SubmodelProvider.java
@@ -0,0 +1,259 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.restapi;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Pattern;
+
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.facade.SubmodelElementMapCollectionConverter;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation;
+import org.eclipse.basyx.submodel.restapi.api.ISubmodelAPI;
+import org.eclipse.basyx.submodel.restapi.vab.VABSubmodelAPI;
+import org.eclipse.basyx.vab.exception.provider.MalformedRequestException;
+import org.eclipse.basyx.vab.exception.provider.ProviderException;
+import org.eclipse.basyx.vab.modelprovider.VABPathTools;
+import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
+import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaProvider;
+
+/**
+ * Additional VAB provider specific for providing submodels together
+ * with other SDKs by implementing the submodel API.
+ *
+ * The VAB provides generic models without considering high-level information.
+ * For example, Operation submodel elements are realized as a Map. The function
+ * is contained and can be accessed at /operations/opId/invokable. Therefore
+ * invoking the Operation directly at /operations/opId/ attempts to invoke the
+ * Map, which does not have any effect for the VABModelProvider.
+ *
+ * This provider maps these requests to the VAB primitives to generate the
+ * desired behavior as it is described in the BaSys documentation.
+ *
+ * @author espen, schnicke
+ *
+ */
+public class SubmodelProvider implements IModelProvider {
+
+	public static final String VALUES = "values";
+	public static final String SUBMODEL = "submodel";
+	
+	ISubmodelAPI submodelAPI;
+
+	/**
+	 * Default constructor - based on an empty submodel with a lambda provider
+	 */
+	public SubmodelProvider() {
+		this(new Submodel());
+	}
+
+	/**
+	 * Creates a SubmodelProvider based on the VAB API, wrapping the passed provider
+	 * 
+	 * @param provider
+	 *            to be wrapped by submodel API
+	 */
+	public SubmodelProvider(IModelProvider provider) {
+		submodelAPI = new VABSubmodelAPI(provider);
+	}
+
+	/**
+	 * Creates a SubmodelProvider based on a lambda provider and a given model
+	 */
+	public SubmodelProvider(Submodel model) {
+		submodelAPI = new VABSubmodelAPI(new VABLambdaProvider(model));
+	}
+
+	/**
+	 * Creates a SubmodelProvider based on a given ISubmodelAPI.
+	 */
+	public SubmodelProvider(ISubmodelAPI submodelAPI) {
+		this.submodelAPI = submodelAPI;
+	}
+
+	/**
+	 * Strips submodel prefix if it exists
+	 *
+	 * @param path
+	 * @return
+	 */
+	private String removeSubmodelPrefix(String path) {
+		path = VABPathTools.stripSlashes(path);
+		String submodelWithSlash = SUBMODEL + "/";
+		if (path.startsWith(submodelWithSlash)) {
+			path = path.replaceFirst("submodel/", "");
+		} else if (path.equals(SUBMODEL)) {
+			path = "";
+		}
+		path = VABPathTools.stripSlashes(path);
+		return path;
+	}
+
+	@Override
+	public Object getValue(String path) throws ProviderException {
+		VABPathTools.checkPathForNull(path);
+		path = removeSubmodelPrefix(path);
+		if (path.isEmpty()) {
+			ISubmodel sm = submodelAPI.getSubmodel();
+
+			// Change internal map representation to set
+			if (sm instanceof Submodel) {
+				return SubmodelElementMapCollectionConverter.smToMap((Submodel) sm);
+			} else {
+				return sm;
+			}
+		} else {
+			String[] splitted = VABPathTools.splitPath(path);
+			// Request for submodelElements
+			if (splitted.length == 1 && splitted[0].equals(VALUES)) {
+				// Request for values of all submodelElements
+				return submodelAPI.getSubmodel().getValues();
+			} else if (splitted.length == 1 && splitted[0].equals(MultiSubmodelElementProvider.ELEMENTS)) {
+				return submodelAPI.getSubmodelElements();
+			} else if (splitted.length >= 2 && isQualifier(splitted[0])) { // Request for element with specific idShort
+				// Remove initial "/submodelElements"
+				path = removeSMElementPrefix(path);
+
+                if (endsWithValue(splitted)) { // Request for the value of an property
+                    String idShortPath = path.replaceFirst(Pattern.quote("/value"), "");
+                    return submodelAPI.getSubmodelElementValue(idShortPath);
+                } else if (isInvocationListPath(splitted)) {
+                    List<String> idShorts = getIdShorts(splitted);
+
+                    // Remove invocationList/{requestId} from the idShorts
+                    idShorts.remove(idShorts.size() - 1);
+                    idShorts.remove(idShorts.size() - 1);
+                    return submodelAPI.getOperationResult(idShorts.get(0), splitted[splitted.length - 1]);
+                } else {
+                    return submodelAPI.getSubmodelElement(path);
+                }
+            }
+        }
+        throw new MalformedRequestException("Unknown path " + path + " was requested");
+	}
+
+	private List<String> getIdShorts(String[] splitted) {
+		// Create list from array and wrap it in ArrayList to ensure modifiability
+		List<String> idShorts = new ArrayList<>(Arrays.asList(splitted));
+
+		// Drop inital "submodelElements"
+		idShorts.remove(0);
+
+		// If value is contained in path, remove it
+		if (splitted[splitted.length - 1].equals(Property.VALUE)) {
+			idShorts.remove(idShorts.size() - 1);
+		}
+		return idShorts;
+	}
+
+
+	private boolean endsWithValue(String[] splitted) {
+		return splitted[splitted.length - 1].equals(Property.VALUE);
+	}
+
+
+	private boolean isInvocationListPath(String[] splitted) {
+		return splitted.length > 2 && splitted[splitted.length - 2].equals(OperationProvider.INVOCATION_LIST);
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public void setValue(String path, Object newValue) throws ProviderException {
+		path = removeSubmodelPrefix(path);
+		if (path.isEmpty()) {
+			throw new MalformedRequestException("Set on \"submodel\" not supported");
+		} else {
+			String[] splitted = VABPathTools.splitPath(path);
+			path = removeSMElementPrefix(path);
+			String idshortPath = path.replaceFirst(Pattern.quote("/value"), "");
+			if (endsWithValue(splitted)) {
+				submodelAPI.updateSubmodelElement(idshortPath, newValue);
+			} else {
+				
+				SubmodelElement element = SubmodelElement.createAsFacade((Map<String, Object>) newValue);
+				
+				if(!path.endsWith(element.getIdShort())) {
+					throw new MalformedRequestException("The idShort of given Element '"
+							+ element.getIdShort() + "' does not match the ending of the given path '" + path + "'");
+				}
+				
+				submodelAPI.addSubmodelElement(idshortPath, element);
+			}
+		}
+	}
+
+	@Override
+	public void createValue(String path, Object newEntity) throws ProviderException {
+		throw new MalformedRequestException("POST (create) on '" + path + "' not allowed. Use PUT (set) instead.");
+	}
+
+	@Override
+	public void deleteValue(String path) throws ProviderException {
+		path = removeSubmodelPrefix(path);
+		if (!path.isEmpty()) {
+			String[] splitted = VABPathTools.splitPath(path);
+			if (isQualifier(splitted[0])) {
+				if (splitted.length > 2) {
+					path = removeSMElementPrefix(path);
+					submodelAPI.deleteSubmodelElement(path);
+				} else {
+					submodelAPI.deleteSubmodelElement(splitted[1]);
+				}
+			} else {
+				throw new MalformedRequestException("Path " + path + " not supported for delete");
+			}
+		} else {
+			throw new MalformedRequestException("Path \"submodel\" not supported for delete");
+		}
+	}
+
+	private boolean isQualifier(String str) {
+		return str.equals(MultiSubmodelElementProvider.ELEMENTS);
+	}
+
+	@Override
+	public void deleteValue(String path, Object obj) throws ProviderException {
+		throw new MalformedRequestException("Delete with a passed argument not allowed");
+	}
+
+	@Override
+	public Object invokeOperation(String path, Object... parameters) throws ProviderException {
+		path = removeSubmodelPrefix(path);
+		if (path.isEmpty()) {
+			throw new MalformedRequestException("Given path must not be empty");
+		} else {
+			if (VABPathTools.isOperationInvokationPath(path)) {
+				if(path.endsWith(OperationProvider.ASYNC)) {
+					path = removeSMElementPrefix(path);
+					path = path.replaceFirst(Pattern.quote(Operation.INVOKE + OperationProvider.ASYNC), "");
+					return submodelAPI.invokeAsync(path, parameters);
+				} else {
+					path = removeSMElementPrefix(path);
+					return submodelAPI.invokeOperation(path, parameters);
+				}
+			} else {
+				throw new MalformedRequestException("Given path '" + path + "' does not end in /invoke");
+			}
+		}
+	}
+
+	protected void setAPI(ISubmodelAPI api) {
+		this.submodelAPI = api;
+	}
+	
+	private String removeSMElementPrefix(String path) {
+		return  path.replaceFirst(MultiSubmodelElementProvider.ELEMENTS, "");
+	}
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/api/ISubmodelAPI.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/api/ISubmodelAPI.java
index 214e7b7..0ba527b 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/api/ISubmodelAPI.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/api/ISubmodelAPI.java
@@ -1,11 +1,18 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.restapi.api;
 
 import java.util.Collection;
-import java.util.List;
 
-import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
 import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
-import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
 import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperation;
 
 /**
@@ -21,39 +28,43 @@
 	 * 
 	 * @return the submodel
 	 */
-	public ISubModel getSubmodel();
+	public ISubmodel getSubmodel();
 
 	/**
-	 * Returns all submodel elements contained by the submodel
-	 * 
-	 * @return the submodel elements
-	 */
-	public Collection<ISubmodelElement> getElements();
-
-	/**
-	 * Adds a submodel element to the submodel
+	 * Adds a submodelElement to the submodel
 	 * 
 	 * @param elem
-	 *            the element to be added
+	 *            the submodelElement to be added
 	 */
 	public void addSubmodelElement(ISubmodelElement elem);
 
 	/**
-	 * Retrieves a submodel element
+	 * Adds a submodelElement to the submodel
 	 * 
-	 * @param idShort
-	 *            of the submodel element
-	 * @return the submodel element
+	 * @param idShortPath
+	 *            the idShort path to the submodelElement
+	 * @param  elem
+	 *            the submodelElement to be added
 	 */
-	public ISubmodelElement getSubmodelElement(String idShort);
+	public void addSubmodelElement(String idShortPath, ISubmodelElement elem);
 
 	/**
-	 * Removes a submodel element from the submodel
+	 * Retrieves a submodelElement
 	 * 
-	 * @param idShort
-	 *            of the element to be removed
+	 * @param idShortPath
+	 *            the idShort Path to the submodelElement
+	 * @return the submodelElement
 	 */
-	public void deleteSubmodelElement(String idShort);
+	public ISubmodelElement getSubmodelElement(String idShortPath);
+
+	/**
+	 * Removes a submodelElement from the submodel
+	 * 
+	 * @param idShortPath
+	 *            the idShort path to the submodelElement, which is to be removed
+	 */
+	public void deleteSubmodelElement(String idShortPath);
+
 
 	/**
 	 * Helper function for quick access of operations
@@ -63,56 +74,64 @@
 	public Collection<IOperation> getOperations();
 
 	/**
-	 * Helper function for quick access of properties
+	 * Helper function for quick access of submodelElements
 	 * 
-	 * @return all properties contained by the submodel
+	 * @return all submodelElements contained by the submodel
 	 */
-	public Collection<IProperty> getProperties();
+	public Collection<ISubmodelElement> getSubmodelElements();
 
 	/**
-	 * Updates the value of a property
+	 * Updates the value of a submodelElement
 	 * 
-	 * @param idShort
-	 *            of the property
+	 * @param idShortPath
+	 *            the idShort path to the submodelElement
 	 * @param newValue
-	 *            new value of the property
+	 *            new value of the submodelElement
 	 */
-	public void updateProperty(String idShort, Object newValue);
+	public void updateSubmodelElement(String idShortPath, Object newValue);
 
 	/**
-	 * Retrieves the value of a property
+	 * Retrieves the value of a submodelElement
 	 * 
-	 * @param idShort
-	 *            of the property
-	 * @return property value
+	 * @param idShortPath
+	 *            the idShort path to the submodelElement
+	 * @return submodelElement value
 	 */
-	public Object getPropertyValue(String idShort);
+	public Object getSubmodelElementValue(String idShortPath);
 
-	/**
-	 * Retrieves the value of a property nested inside a SubmodelElementCollection.
-	 * 
-	 * @param idShorts
-	 *            the idShort path to the property
-	 */
-	public Object getNestedPropertyValue(List<String> idShorts);
-
-	/**
-	 * Retrieves a submodel element nested inside a SubmodelElementCollection
-	 * 
-	 * @param idShorts
-	 *            the idShort path to the property
-	 * @return
-	 */
-	public ISubmodelElement getNestedSubmodelElement(List<String> idShorts);
 
 	/**
 	 * Invokes an operation
 	 * 
-	 * @param idShort
-	 *            of the operation
+	 * @param idShortPath
+	 *            the idShort path to the operation
 	 * @param params
 	 *            to be passed to the operation
 	 * @return the result of the operation
 	 */
-	public Object invokeOperation(String idShort, Object... params);
+	public Object invokeOperation(String idShortPath, Object... params);
+
+	
+	/**
+	 * Invoke an operation asynchronously
+	 * 
+	 * @param idShortPath
+	 * 			the idShort path to the operation
+	 * @param params
+	 * 			to be passed to the operation
+	 * @return the requestId of the invocation
+	 */
+	public Object invokeAsync(String idShortPath, Object... params);
+	
+	/**
+	 * Gets the result of an asynchronously invoked operation
+	 * 
+	 * @param idShort 
+	 *            of the operation
+	 * @param requestId
+	 *            the requestId of the invocation
+	 * @return the result of the Operation or a Message that it is not finished yet
+	 */
+	public Object getOperationResult(String idShort, String requestId);
+
 }
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/api/ISubmodelAPIFactory.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/api/ISubmodelAPIFactory.java
new file mode 100644
index 0000000..a5ef08c
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/api/ISubmodelAPIFactory.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.restapi.api;
+
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+
+/**
+ * Interface for providing an Submodel API
+ * 
+ * @author espen
+ *
+ */
+public interface ISubmodelAPIFactory {
+	/**
+	 * Return a constructed Submodel API
+	 * 
+	 * @return
+	 */
+	public ISubmodelAPI getSubmodelAPI(Submodel submodel);
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/operation/AsyncOperationHandler.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/operation/AsyncOperationHandler.java
new file mode 100644
index 0000000..d09b172
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/operation/AsyncOperationHandler.java
@@ -0,0 +1,157 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.restapi.operation;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.poi.ss.formula.functions.T;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperationVariable;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.OperationExecutionTimeoutException;
+import org.eclipse.basyx.vab.exception.provider.ProviderException;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
+
+/**
+ * Helperclass used to keep and invoke operations asynchronously.
+ * 
+ * @author conradi, espen
+ *
+ */
+public class AsyncOperationHandler {
+	private static Map<String, InvocationResponse> responses = new HashMap<>();
+	private static Map<String, String> responseOperationMap = new HashMap<>();
+	private static ScheduledThreadPoolExecutor delayer = new ScheduledThreadPoolExecutor(0);
+
+	/**
+	 * Invokes an Operation with an invocation request
+	 */
+	public static void invokeAsync(IModelProvider provider, String operationId, InvocationRequest request,
+			Collection<IOperationVariable> outputArguments) {
+		String requestId = request.getRequestId();
+		Collection<IOperationVariable> inOutArguments = request.getInOutArguments();
+		Object[] parameters = request.unwrapInputParameters();
+		invokeAsync(provider, operationId, requestId, parameters, inOutArguments, outputArguments,
+				request.getTimeout());
+	}
+
+	/**
+	 * Invokes an Operation without an invocation request
+	 */
+	public static void invokeAsync(IModelProvider provider, String operationId, String requestId, Object[] inputs,
+			Collection<IOperationVariable> outputArguments, int timeout) {
+		invokeAsync(provider, operationId, requestId, inputs, new ArrayList<>(), outputArguments, timeout);
+	}
+
+	/**
+	 * Invokes an Operation and returns its requestId
+	 */
+	private static void invokeAsync(IModelProvider provider, String operationId, String requestId, Object[] inputs,
+			Collection<IOperationVariable> inOutArguments,
+			Collection<IOperationVariable> outputArguments, int timeout) {
+		synchronized (responses) {
+			InvocationResponse response = new InvocationResponse(requestId, inOutArguments, outputArguments,
+					ExecutionState.INITIATED);
+
+			responses.put(requestId, response);
+			responseOperationMap.put(requestId, operationId);
+
+			CompletableFuture.supplyAsync(
+					// Run Operation asynchronously
+					() -> provider.invokeOperation("", inputs))
+					// Accept either result or throw exception on timeout
+					.acceptEither(setTimeout(timeout, requestId), result -> {
+						// result accepted? => Write execution state if there is an output
+						response.setExecutionState(ExecutionState.COMPLETED);
+						if (!response.getOutputArguments().isEmpty()) {
+							IOperationVariable output = response.getOutputArguments().iterator().next();
+							output.getValue().setValue(result);
+						}
+					}).exceptionally(throwable -> {
+						// result not accepted? set operation state
+						ProviderException exception = null;
+						if (throwable.getCause() instanceof OperationExecutionTimeoutException) {
+							response.setExecutionState(ExecutionState.TIMEOUT);
+							exception = new ProviderException("Request " + requestId + " timed out", throwable);
+						} else {
+							response.setExecutionState(ExecutionState.FAILED);
+							exception = new ProviderException("Request " + requestId + " failed", throwable);
+						}
+						// set provider exception if there is an output
+						if (!response.getOutputArguments().isEmpty()) {
+							IOperationVariable output = response.getOutputArguments().iterator().next();
+							output.getValue().setValue(exception);
+						}
+						return null;
+					});
+		}
+	}
+	
+	/**
+	 * Function for scheduling a timeout function with completable futures
+	 */
+	private static CompletableFuture<T> setTimeout(int timeout, String requestId) {
+		CompletableFuture<T> result = new CompletableFuture<>();
+		delayer.schedule(
+				() -> result.completeExceptionally(
+						new OperationExecutionTimeoutException("Request " + requestId + " timed out")),
+				timeout, TimeUnit.MILLISECONDS);
+		return result;
+	}
+
+	/**
+	 * Gets the result of an invocation
+	 * 
+	 * @param operationIdShort the id of the requested Operation
+	 * @param requestId the id of the request
+	 * @return the result of the Operation or a Message that it is not yet finished
+	 */
+	public static Object retrieveResult(String requestId, String operationId) {
+		// Remove the Invocation if it is finished and its result was retrieved
+		synchronized (responses) {
+			if (!responses.containsKey(requestId)) {
+				throw new ResourceNotFoundException(
+						"RequestId '" + requestId + "' not found for operation '" + operationId + "'.");
+			}
+		
+			String validOperationId = responseOperationMap.get(requestId);
+			if (!operationId.equals(validOperationId)) {
+				throw new ResourceNotFoundException(
+						"RequestId '" + requestId + "' does not belong to Operation '" + operationId + "'");
+			}
+
+			InvocationResponse response = responses.get(requestId);
+			if (ExecutionState.COMPLETED == response.getExecutionState()
+					|| ExecutionState.TIMEOUT == response.getExecutionState()
+					|| ExecutionState.FAILED == response.getExecutionState()) {
+				responses.remove(requestId);
+				responseOperationMap.remove(requestId);
+			}
+			return response;
+		}
+	}
+	
+	/**
+	 * Checks if a given requestId exists
+	 * 
+	 * @param requestId the id to be checked
+	 * @return if the id exists
+	 */
+	public static boolean hasRequestId(String requestId) {
+		synchronized (responses) {
+			return responses.containsKey(requestId);
+		}
+	}
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/operation/CallbackResponse.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/operation/CallbackResponse.java
new file mode 100644
index 0000000..fb10125
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/operation/CallbackResponse.java
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.restapi.operation;
+
+import java.util.Map;
+
+import org.eclipse.basyx.vab.model.VABModelMap;
+
+/**
+ * Direct response when invoking an async operation
+ * 
+ * @author espen
+ *
+ */
+public class CallbackResponse extends VABModelMap<Object> {
+	public static final String REQUESTID = "requestId";
+	public static final String CALLBACKURL = "callbackUrl";
+	
+	public CallbackResponse() {
+	}
+	
+	public static CallbackResponse createAsFacade(Map<String, Object> map) {
+		if (map == null) {
+			return null;
+		}
+
+		CallbackResponse ret = new CallbackResponse();
+		ret.setRequestId((String) map.get(REQUESTID));
+		ret.setCallbackUrl((String) map.get(CALLBACKURL));
+
+		return ret;
+	}
+
+	public CallbackResponse(String requestId, String url) {
+		setRequestId(requestId);
+		put(CALLBACKURL, url);
+	}
+
+	public String getRequestId() {
+		return (String) get(REQUESTID);
+	}
+
+	public void setRequestId(String requestId) {
+		put(REQUESTID, requestId);
+	}
+
+	public String getCallbackUrl() {
+		return (String) get(CALLBACKURL);
+	}
+
+	public void setCallbackUrl(String callbackUrl) {
+		put(CALLBACKURL, callbackUrl);
+	}
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/operation/ExecutionState.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/operation/ExecutionState.java
new file mode 100644
index 0000000..4e085cb
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/operation/ExecutionState.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.restapi.operation;
+
+import org.eclipse.basyx.submodel.metamodel.enumhelper.StandardizedLiteralEnum;
+import org.eclipse.basyx.submodel.metamodel.enumhelper.StandardizedLiteralEnumHelper;
+
+/**
+ * ExecutionState for Operations
+ * 
+ * @author espen
+ *
+ */
+public enum ExecutionState implements StandardizedLiteralEnum {
+
+	/**
+	 * Initial state
+	 */
+	INITIATED("Initiated"),
+	/**
+	 * State during execution
+	 */
+	RUNNING("Running"),
+	/**
+	 * Operation has been completed
+	 */
+	COMPLETED("Completed"),
+	/**
+	 * Operation has been canceled
+	 */
+	CANCELED("Canceled"),
+	/**
+	 * Operation has failed
+	 */
+	FAILED("Failed"),
+	/**
+	 * Operation has timed out
+	 */
+	TIMEOUT("Timeout");
+
+	private String standardizedLiteral;
+
+	private ExecutionState(String standardizedLiteral) {
+		this.standardizedLiteral = standardizedLiteral;
+	}
+
+	@Override
+	public String getStandardizedLiteral() {
+		return standardizedLiteral;
+	}
+	
+	@Override
+	public String toString() {
+		return standardizedLiteral;
+	}
+
+	public static ExecutionState fromString(String str) {
+		return StandardizedLiteralEnumHelper.fromLiteral(ExecutionState.class, str);
+	}
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/operation/InvocationRequest.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/operation/InvocationRequest.java
new file mode 100644
index 0000000..4b0178e
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/operation/InvocationRequest.java
@@ -0,0 +1,136 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.restapi.operation;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperationVariable;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.OperationVariable;
+import org.eclipse.basyx.vab.model.VABModelMap;
+
+/**
+ * Request for invoking operation submodel elements
+ * 
+ * @author schnicke
+ *
+ */
+public class InvocationRequest extends VABModelMap<Object> {
+	public static final String REQUESTID = "requestId";
+	public static final String INOUTARGUMENTS = "inoutputArguments";
+	public static final String INPUTARGUMENTS = "inputArguments";
+	public static final String TIMEOUT = "timeout";
+
+	private InvocationRequest() {
+	}
+
+	public InvocationRequest(String requestId, Collection<IOperationVariable> inoutArguments, Collection<IOperationVariable> inputArguments, int timeout) {
+		put(REQUESTID, requestId);
+		put(INOUTARGUMENTS, inoutArguments);
+		put(INPUTARGUMENTS, inputArguments);
+		put(TIMEOUT, timeout);
+	}
+
+	public static InvocationRequest createAsFacade(Map<String, Object> map) {
+		if (map == null) {
+			return null;
+		}
+		
+		InvocationRequest ret = new InvocationRequest();
+		ret.setRequestId((String) map.get(REQUESTID));
+		Collection<IOperationVariable> inoutArguments = createInoutArguments(map);
+		ret.setInOutArguments(inoutArguments);
+
+		Collection<IOperationVariable> inputArguments = createInputArguments(map);
+		ret.setInputArguments(inputArguments);
+
+		ret.setTimeout((int) map.get(TIMEOUT));
+
+		return ret;
+	}
+
+	/**
+	 * Unwraps the values of the inputVars in the order of occurance in the collection of input arguments
+	 * 
+	 * @return
+	 */
+	public Object[] unwrapInputParameters() {
+		Collection<IOperationVariable> inputArguments = getInputArguments();
+		Object[] unwrappedParameters = new Object[inputArguments.size()];
+		Iterator<IOperationVariable> iterator = inputArguments.iterator();
+		int i = 0;
+		while (iterator.hasNext()) {
+			IOperationVariable next = iterator.next();
+			unwrappedParameters[i] = next.getValue().getValue();
+			i++;
+		}
+		return unwrappedParameters;
+	}
+
+	@SuppressWarnings("unchecked")
+	private static Collection<IOperationVariable> createInputArguments(Map<String, Object> map) {
+		Collection<Map<String, Object>> inputMap = (Collection<Map<String, Object>>) map.get(INPUTARGUMENTS);
+		return createOperationVariables(inputMap);
+	}
+
+	/**
+	 * @param map
+	 */
+	@SuppressWarnings("unchecked")
+	private static Collection<IOperationVariable> createInoutArguments(Map<String, Object> map) {
+		Collection<Map<String, Object>> inoutMap = (Collection<Map<String, Object>>) map.get(INOUTARGUMENTS);
+		return createOperationVariables(inoutMap);
+	}
+
+	private static Collection<IOperationVariable> createOperationVariables(Collection<Map<String, Object>> variableMap) {
+		if (variableMap != null) {
+			return variableMap.stream().map(OperationVariable::createAsFacade).collect(Collectors.toList());
+		} else {
+			return new ArrayList<>();
+		}
+	}
+
+	private void setRequestId(String request) {
+		put(REQUESTID, request);
+	}
+
+	private void setInOutArguments(Collection<IOperationVariable> inoutArguments) {
+		put(INOUTARGUMENTS, inoutArguments);
+	}
+
+	private void setInputArguments(Collection<IOperationVariable> inputArguments) {
+		put(INPUTARGUMENTS, inputArguments);
+	}
+
+	private void setTimeout(int timeout) {
+		put(TIMEOUT, timeout);
+	}
+
+	public String getRequestId() {
+		return (String) get(REQUESTID);
+	}
+
+	@SuppressWarnings("unchecked")
+	public Collection<IOperationVariable> getInOutArguments() {
+		return (Collection<IOperationVariable>) get(INOUTARGUMENTS);
+	}
+
+	@SuppressWarnings("unchecked")
+	public Collection<IOperationVariable> getInputArguments() {
+		return (Collection<IOperationVariable>) get(INPUTARGUMENTS);
+	}
+
+	public int getTimeout() {
+		return (int) get(TIMEOUT);
+	}
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/operation/InvocationResponse.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/operation/InvocationResponse.java
new file mode 100644
index 0000000..78e4170
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/operation/InvocationResponse.java
@@ -0,0 +1,137 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.restapi.operation;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.stream.Collectors;
+
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperationVariable;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.OperationVariable;
+import org.eclipse.basyx.vab.model.VABModelMap;
+
+/**
+ * Response when invoking operation submodel elements
+ * 
+ * @author espen
+ *
+ */
+public class InvocationResponse extends VABModelMap<Object> {
+	public static final String REQUESTID = "requestId";
+	public static final String INOUTARGUMENTS = "inoutputArguments";
+	public static final String OUTPUTARGUMENTS = "outputArguments";
+	public static final String EXECUTIONSTATE = "executionState";
+
+	private InvocationResponse() {
+	}
+
+	public InvocationResponse(String requestId, Collection<IOperationVariable> inoutArguments,
+			Collection<IOperationVariable> outputArguments, ExecutionState executionState) {
+		put(REQUESTID, requestId);
+		put(INOUTARGUMENTS, inoutArguments);
+		put(OUTPUTARGUMENTS, outputArguments);
+		put(EXECUTIONSTATE, executionState.toString());
+	}
+
+	public static InvocationResponse createAsFacade(Map<String, Object> map) {
+		if (map == null) {
+			return null;
+		}
+
+		InvocationResponse resp = new InvocationResponse();
+		resp.setRequestId((String) map.get(REQUESTID));
+		Collection<IOperationVariable> inoutArguments = createInoutArguments(map);
+		resp.setInOutArguments(inoutArguments);
+		Collection<IOperationVariable> outputArguments = createOutputArguments(map);
+		resp.setOutputArguments(outputArguments);
+
+		Object execStateObj = map.get(EXECUTIONSTATE);
+		if (execStateObj instanceof String) {
+			resp.setExecutionState(ExecutionState.fromString((String) execStateObj));
+		} else if (execStateObj instanceof ExecutionState) {
+			resp.setExecutionState((ExecutionState) execStateObj);
+		}
+		return resp;
+	}
+
+	@SuppressWarnings("unchecked")
+	private static Collection<IOperationVariable> createOutputArguments(Map<String, Object> map) {
+		Collection<Map<String, Object>> outputMap = (Collection<Map<String, Object>>) map.get(OUTPUTARGUMENTS);
+		return createOperationVariables(outputMap);
+	}
+
+	/**
+	 * @param map
+	 */
+	@SuppressWarnings("unchecked")
+	private static Collection<IOperationVariable> createInoutArguments(Map<String, Object> map) {
+		Collection<Map<String, Object>> inoutMap = (Collection<Map<String, Object>>) map.get(INOUTARGUMENTS);
+		return createOperationVariables(inoutMap);
+	}
+
+	private static Collection<IOperationVariable> createOperationVariables(
+			Collection<Map<String, Object>> variableMap) {
+		if (variableMap != null) {
+			return variableMap.stream().map(OperationVariable::createAsFacade).collect(Collectors.toList());
+		} else {
+			return new ArrayList<>();
+		}
+	}
+
+	/**
+	 * Gets the first output value of this response
+	 * 
+	 * @return The output value and null, if there is no output
+	 */
+	public Object getFirstOutput() {
+		try {
+			IOperationVariable next = getOutputArguments().iterator().next();
+			return next.getValue().getValue();
+		} catch (NoSuchElementException e) {
+			return null;
+		}
+	}
+
+	private void setRequestId(String request) {
+		put(REQUESTID, request);
+	}
+
+	private void setInOutArguments(Collection<IOperationVariable> inoutArguments) {
+		put(INOUTARGUMENTS, inoutArguments);
+	}
+
+	private void setOutputArguments(Collection<IOperationVariable> inputArguments) {
+		put(OUTPUTARGUMENTS, inputArguments);
+	}
+
+	public void setExecutionState(ExecutionState state) {
+		put(EXECUTIONSTATE, state.toString());
+	}
+
+	public String getRequestId() {
+		return (String) get(REQUESTID);
+	}
+
+	@SuppressWarnings("unchecked")
+	public Collection<IOperationVariable> getInOutArguments() {
+		return (Collection<IOperationVariable>) get(INOUTARGUMENTS);
+	}
+
+	@SuppressWarnings("unchecked")
+	public Collection<IOperationVariable> getOutputArguments() {
+		return (Collection<IOperationVariable>) get(OUTPUTARGUMENTS);
+	}
+
+	public ExecutionState getExecutionState() {
+		return ExecutionState.fromString((String) get(EXECUTIONSTATE));
+	}
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/vab/VABSubmodelAPI.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/vab/VABSubmodelAPI.java
index 0eedee7..3934a04 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/vab/VABSubmodelAPI.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/vab/VABSubmodelAPI.java
@@ -1,23 +1,30 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.submodel.restapi.vab;
 
 import java.util.Collection;
-import java.util.HashSet;
-import java.util.List;
+import java.util.HashMap;
 import java.util.Map;
 import java.util.stream.Collectors;
 
-import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
 import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
-import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
 import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperation;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElement;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation;
-import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
+import org.eclipse.basyx.submodel.restapi.MultiSubmodelElementProvider;
+import org.eclipse.basyx.submodel.restapi.OperationProvider;
 import org.eclipse.basyx.submodel.restapi.api.ISubmodelAPI;
 import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
-import org.eclipse.basyx.vab.modelprovider.VABPathTools;
 import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
 
 /**
@@ -50,109 +57,88 @@
 	 * @return returns the SubmodelElementProvider pointing to the contained
 	 *         submodelelements
 	 */
-	private SubmodelElementProvider getElementProvider() {
-		IModelProvider elementProxy = new VABElementProxy(SubModel.SUBMODELELEMENT, modelProvider);
-		return new SubmodelElementProvider(elementProxy);
+	private MultiSubmodelElementProvider getElementProvider() {
+		IModelProvider elementProxy = new VABElementProxy(Submodel.SUBMODELELEMENT, modelProvider);
+		return new MultiSubmodelElementProvider(elementProxy);
 	}
 
 	@SuppressWarnings("unchecked")
 	@Override
-	public ISubModel getSubmodel() {
+	public ISubmodel getSubmodel() {
 		// For access on the container property root, return the whole model
-		Map<String, Object> map = (Map<String, Object>) modelProvider.getModelPropertyValue("");
+		Map<String, Object> map = (Map<String, Object>) modelProvider.getValue("");
 
-		// Change internal maps to sets for submodelElements
-		setMapToSet(map, SubModel.SUBMODELELEMENT);
-
-		return SubModel.createAsFacade(map);
-	}
-
-	@SuppressWarnings("unchecked")
-	@Override
-	public Collection<ISubmodelElement> getElements() {
-		Collection<Map<String, Object>> operations = (Collection<Map<String, Object>>) getElementProvider().getModelPropertyValue(SubmodelElementProvider.ELEMENTS);
-		return operations.stream().map(e -> SubmodelElement.createAsFacade(e)).collect(Collectors.toList());
+		// Only return a copy of the Submodel
+		Map<String, Object> smCopy = new HashMap<>();
+		smCopy.putAll(map);
+		return Submodel.createAsFacade(smCopy);
 	}
 
 	@Override
 	public void addSubmodelElement(ISubmodelElement elem) {
-		getElementProvider().createValue(SubmodelElementProvider.ELEMENTS + "/" + elem.getIdShort(), elem);
+		getElementProvider().createValue(MultiSubmodelElementProvider.ELEMENTS + "/" + elem.getIdShort(), elem);
 	}
 
 	@Override
-	public void deleteSubmodelElement(String idShort) {
-		getElementProvider().deleteValue(SubmodelElementProvider.ELEMENTS + "/" + idShort);
+	public void addSubmodelElement(String idShortPath, ISubmodelElement elem) {
+		getElementProvider().createValue(MultiSubmodelElementProvider.ELEMENTS + "/" + idShortPath, elem);
 	}
 
-	@SuppressWarnings("unchecked")
+	@Override
+	public void deleteSubmodelElement(String idShortPath) {
+		getElementProvider().deleteValue(MultiSubmodelElementProvider.ELEMENTS + "/" + idShortPath);
+	}
+
+
 	@Override
 	public Collection<IOperation> getOperations() {
-		Collection<Map<String, Object>> operations = (Collection<Map<String, Object>>) getElementProvider().getModelPropertyValue(SubmodelElementProvider.OPERATIONS);
-		return operations.stream().map(e -> Operation.createAsFacade(e)).collect(Collectors.toList());
-	}
-
-
-	/**
-	 * Converts a map entry to a set, if it is also a map
-	 */
-	@SuppressWarnings("unchecked")
-	private void setMapToSet(Map<String, Object> map, String key) {
-		Object mapEntry = map.get(key);
-		if (mapEntry instanceof Map<?, ?>) {
-			Map<String, Object> elements = (Map<String, Object>) mapEntry;
-			map.put(key, new HashSet<Object>(elements.values()));
-		}
+		return getSubmodelElements().stream().filter(e -> e instanceof IOperation).map(e -> (IOperation) e).collect(Collectors.toList());
 	}
 
 	@SuppressWarnings("unchecked")
 	@Override
-	public Collection<IProperty> getProperties() {
-		Collection<Map<String, Object>> props = (Collection<Map<String, Object>>) getElementProvider().getModelPropertyValue(SubmodelElementProvider.PROPERTIES);
-		return props.stream().map(e -> Property.createAsFacade(e)).collect(Collectors.toList());
+	public Collection<ISubmodelElement> getSubmodelElements() {
+		Collection<Map<String, Object>> elements = (Collection<Map<String, Object>>) getElementProvider()
+				.getValue(MultiSubmodelElementProvider.ELEMENTS);
+		return elements.stream().map(SubmodelElement::createAsFacade).collect(Collectors.toList());
 	}
 
 	@Override
-	public void updateProperty(String idShort, Object newValue) {
-		getElementProvider().setModelPropertyValue(buildValuePathForProperty(idShort), newValue);
+	public void updateSubmodelElement(String idShortPath, Object newValue) {
+		getElementProvider().setValue(buildValuePathForProperty(idShortPath), newValue);
 	}
 
 	@Override
-	public Object getPropertyValue(String idShort) {
-		return getElementProvider().getModelPropertyValue(buildValuePathForProperty(idShort));
+	public Object getSubmodelElementValue(String idShortPath) {
+		return getElementProvider().getValue(buildValuePathForProperty(idShortPath));
 	}
 
 	@SuppressWarnings("unchecked")
 	@Override
-	public ISubmodelElement getSubmodelElement(String idShort) {
-		return SubmodelElement.createAsFacade((Map<String, Object>) getElementProvider().getModelPropertyValue(SubmodelElementProvider.ELEMENTS + "/" + idShort));
+	public ISubmodelElement getSubmodelElement(String idShortPath) {
+		return SubmodelElement.createAsFacade((Map<String, Object>) getElementProvider().getValue(MultiSubmodelElementProvider.ELEMENTS + "/" + idShortPath));
 	}
 
 	@Override
-	public Object invokeOperation(String idShort, Object... params) {
-		return getElementProvider().invokeOperation(SubmodelElementProvider.OPERATIONS + "/" + idShort, params);
+	public Object invokeOperation(String idShortPath, Object... params) {
+		return getElementProvider().invokeOperation(MultiSubmodelElementProvider.ELEMENTS + "/" + idShortPath, params);
 	}
-
-	private String buildValuePathForProperty(String idShort) {
-		return SubmodelElementProvider.PROPERTIES + "/" + idShort + "/" + Property.VALUE;
-	}
-
+	
+	
 	@Override
-	public Object getNestedPropertyValue(List<String> idShorts) {
-		return getElementProvider().getModelPropertyValue(buildNestedElementPath(idShorts) + "/" + Property.VALUE);
+	public Object invokeAsync(String idShortPath, Object... params) {
+		return getElementProvider().invokeOperation(MultiSubmodelElementProvider.ELEMENTS + "/" + idShortPath +"/" + Operation.INVOKE + OperationProvider.ASYNC, params);
 	}
 
-	@SuppressWarnings("unchecked")
+	private String buildValuePathForProperty(String idShortPath) {
+		return MultiSubmodelElementProvider.ELEMENTS + "/" + idShortPath + "/" + Property.VALUE;
+	}
+
+	
 	@Override
-	public ISubmodelElement getNestedSubmodelElement(List<String> idShorts) {
-		Map<String, Object> map = (Map<String, Object>) getElementProvider().getModelPropertyValue(buildNestedElementPath(idShorts));
-		return SubmodelElement.createAsFacade(map);
+	public Object getOperationResult(String idShortPath, String requestId) {
+		return getElementProvider().getValue(MultiSubmodelElementProvider.ELEMENTS + "/" + idShortPath + "/" + OperationProvider.INVOCATION_LIST + "/" + requestId);
 	}
 
-	/**
-	 * @param idShorts
-	 * @return
-	 */
-	private String buildNestedElementPath(List<String> idShorts) {
-		return SubmodelElementProvider.ELEMENTS + "/" + VABPathTools.concatenatePaths(idShorts.toArray(new String[1]));
-	}
+
 }
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/vab/VABSubmodelAPIFactory.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/vab/VABSubmodelAPIFactory.java
new file mode 100644
index 0000000..a547c9c
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/vab/VABSubmodelAPIFactory.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.restapi.vab;
+
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.restapi.api.ISubmodelAPI;
+import org.eclipse.basyx.submodel.restapi.api.ISubmodelAPIFactory;
+import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaProvider;
+
+/**
+ * Submodel API provider that provides the default VAB Submodel API
+ * 
+ * @author espen
+ *
+ */
+public class VABSubmodelAPIFactory implements ISubmodelAPIFactory {
+	@Override
+	public ISubmodelAPI getSubmodelAPI(Submodel submodel) {
+		return new VABSubmodelAPI(new VABLambdaProvider(submodel));
+	}
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/DigitalNameplateSubmodel.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/DigitalNameplateSubmodel.java
new file mode 100644
index 0000000..1e76b2b
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/DigitalNameplateSubmodel.java
@@ -0,0 +1,446 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.types.digitalnameplate;
+
+import java.util.Collections;
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyType;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IMultiLanguageProperty;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
+import org.eclipse.basyx.submodel.metamodel.facade.SubmodelElementMapCollectionConverter;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangString;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangStrings;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.MultiLanguageProperty;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.submodel.types.digitalnameplate.submodelelementcollections.address.Address;
+import org.eclipse.basyx.submodel.types.digitalnameplate.submodelelementcollections.assetspecificproperties.AssetSpecificProperties;
+import org.eclipse.basyx.submodel.types.digitalnameplate.submodelelementcollections.markings.Markings;
+
+/**
+ * DigitalNameplateSubmodel as defined in the AAS Digital Nameplate Template document <br/>
+ * this contains the nameplate information attached to the product
+ * 
+ * @author haque
+ *
+ */
+public class DigitalNameplateSubmodel extends Submodel {
+	public static final String MANUFACTURERNAMEID = "ManufacturerName";
+	public static final String MANUFACTURERPRODUCTDESIGNATIONID = "ManufacturerProductDesignation";
+	public static final String ADDRESSID = "Address";
+	public static final String MANUFACTURERPRODUCTFAMILYID = "ManufacturerProductFamily";
+	public static final String SERIALNUMBERID = "SerialNumber";
+	public static final String YEARSOFCONSTRUCTIONID = "YearOfConstruction";
+	public static final String MARKINGSID = "Markings";
+	public static final String ASSETSPECIFICPROPERTIESID = "AssetSpecificProperties";
+	public static final Reference SEMANTICID = new Reference(Collections.singletonList(new Key(KeyElements.CONCEPTDESCRIPTION, false, "https://admin-shell.io/zvei/nameplate/1/0/Nameplate", KeyType.IRI)));
+	public static final String SUBMODELID = "Nameplate";
+	
+	private DigitalNameplateSubmodel() {}
+	
+	/**
+	 * Constructor with default idShort
+	 * @param identifier
+	 * @param manufacturerName
+	 * @param manufacturerProductDesignation
+	 * @param address
+	 * @param manufacturerProductFamily
+	 * @param yearsOfConstruction
+	 */
+	public DigitalNameplateSubmodel(
+			Identifier identifier,
+			MultiLanguageProperty manufacturerName, 
+			MultiLanguageProperty manufacturerProductDesignation, 
+			Address address, 
+			MultiLanguageProperty manufacturerProductFamily, 
+			Property yearsOfConstruction
+			) {
+		this(SUBMODELID, identifier, manufacturerName, manufacturerProductDesignation, address, manufacturerProductFamily, yearsOfConstruction);
+	}
+	
+	/**
+	 * Constructor with default idShort
+	 * @param identifier
+	 * @param manufacturerName
+	 * @param manufacturerProductDesignation
+	 * @param address
+	 * @param manufacturerProductFamily
+	 * @param yearsOfConstruction
+	 */
+	public DigitalNameplateSubmodel(
+			Identifier identifier,
+			LangString manufacturerName, 
+			LangString manufacturerProductDesignation, 
+			Address address, 
+			LangString manufacturerProductFamily, 
+			String yearsOfConstruction
+			) {
+		this(SUBMODELID, identifier, manufacturerName, manufacturerProductDesignation, address, manufacturerProductFamily, yearsOfConstruction);
+	}
+	
+	/**
+	 * Constructor with mandatory attributes
+	 * @param idShort
+	 * @param identifier
+	 * @param manufacturerName
+	 * @param manufacturerProductDesignation
+	 * @param address
+	 * @param manufacturerProductFamily
+	 * @param yearsOfConstruction
+	 */
+	public DigitalNameplateSubmodel(
+			String idShort, 
+			Identifier identifier,
+			MultiLanguageProperty manufacturerName, 
+			MultiLanguageProperty manufacturerProductDesignation, 
+			Address address, 
+			MultiLanguageProperty manufacturerProductFamily, 
+			Property yearsOfConstruction
+			) {
+		super(idShort, identifier);
+		setSemanticId(SEMANTICID);
+		setManufacturerName(manufacturerName);
+		setManufacturerProductDesignation(manufacturerProductDesignation);
+		setAddress(address);
+		setManufacturerProductFamily(manufacturerProductFamily);
+		setYearOfConstruction(yearsOfConstruction);
+	}
+	
+	/**
+	 * Constructor with mandatory attributes
+	 * @param idShort
+	 * @param identifier
+	 * @param manufacturerName
+	 * @param manufacturerProductDesignation
+	 * @param address
+	 * @param manufacturerProductFamily
+	 * @param yearsOfConstruction
+	 */
+	public DigitalNameplateSubmodel(
+			String idShort, 
+			Identifier identifier,
+			LangString manufacturerName, 
+			LangString manufacturerProductDesignation, 
+			Address address, 
+			LangString manufacturerProductFamily, 
+			String yearsOfConstruction
+			) {
+		super(idShort, identifier);
+		setSemanticId(SEMANTICID);
+		setManufacturerName(manufacturerName);
+		setManufacturerProductDesignation(manufacturerProductDesignation);
+		setAddress(address);
+		setManufacturerProductFamily(manufacturerProductFamily);
+		setYearOfConstruction(yearsOfConstruction);
+	}
+	
+	/**
+	 * Creates a DigitalNameplateSubmodel object from a map
+	 * 
+	 * @param obj a DigitalNameplateSubmodel SMC object as raw map
+	 * @return a DigitalNameplateSubmodel SMC object, that behaves like a facade for the given map
+	 */
+	public static DigitalNameplateSubmodel createAsFacade(Map<String, Object> obj) {
+		if (obj == null) {
+			return null;
+		}
+		
+		if (!isValid(obj)) {
+			throw new MetamodelConstructionException(DigitalNameplateSubmodel.class, obj);
+		}
+		
+		DigitalNameplateSubmodel ret = new DigitalNameplateSubmodel();
+		ret.setMap(SubmodelElementMapCollectionConverter.mapToSM(obj));
+		return ret;
+	}
+	
+	/**
+	 * Creates a DigitalNameplateSubmodel object from a map without validation
+	 * 
+	 * @param obj a DigitalNameplateSubmodel SMC object as raw map
+	 * @return a DigitalNameplateSubmodel SMC object, that behaves like a facade for the given map
+	 */
+	private static DigitalNameplateSubmodel createAsFacadeNonStrict(Map<String, Object> obj) {
+		if (obj == null) {
+			return null;
+		}
+		
+		DigitalNameplateSubmodel ret = new DigitalNameplateSubmodel();
+		ret.setMap(SubmodelElementMapCollectionConverter.mapToSM(obj));
+		return ret;
+	}
+	
+	/**
+	 * Check whether all mandatory elements for DigitalNameplateSubmodel
+	 * exist in the map
+	 * 
+	 * @param obj
+	 * 
+	 * @return true/false
+	 */
+	@SuppressWarnings("unchecked")
+	public static boolean isValid(Map<String, Object> obj) {
+		DigitalNameplateSubmodel submodel = createAsFacadeNonStrict(obj);
+		
+		return Submodel.isValid(obj)
+				&& MultiLanguageProperty.isValid((Map<String, Object>) submodel.getManufacturerName())
+				&& MultiLanguageProperty.isValid((Map<String, Object>) submodel.getManufacturerProductDesignation())
+				&& Address.isValid(submodel.getAddress())
+				&& MultiLanguageProperty.isValid((Map<String, Object>) submodel.getManufacturerProductFamily())
+				&& Property.isValid((Map<String, Object>) submodel.getYearOfConstruction());
+	}
+	
+	/**
+	 * Sets manufacturerName
+	 * legally valid designation of the natural or judicial person which is directly
+     * responsible for the design, production, packaging and labeling of a product
+     * in respect to its being brought into circulation
+     * Note: mandatory property according to EU Machine Directive
+     * 2006/42/EC.
+	 * @param manufacturerName {@link MultiLanguageProperty}
+	 */
+	public void setManufacturerName(MultiLanguageProperty manufacturerName) {
+		addSubmodelElement(manufacturerName);
+	}
+	
+	/**
+	 * Sets manufacturerName
+	 * legally valid designation of the natural or judicial person which is directly
+     * responsible for the design, production, packaging and labeling of a product
+     * in respect to its being brought into circulation
+     * Note: mandatory property according to EU Machine Directive
+     * 2006/42/EC.
+	 * @param manufacturerName {@link LangString}
+	 */
+	public void setManufacturerName(LangString manufacturerName) {
+		MultiLanguageProperty manufacturerNameProp = new MultiLanguageProperty(MANUFACTURERNAMEID);
+		manufacturerNameProp.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "0173-1#02-AAO677#002", IdentifierType.IRDI)));
+		manufacturerNameProp.setValue(new LangStrings(manufacturerName));
+		setManufacturerName(manufacturerNameProp);
+	}
+	
+	/**
+	 * 
+	 * Gets manufacturerName
+	 * legally valid designation of the natural or judicial person which is directly
+     * responsible for the design, production, packaging and labeling of a product
+     * in respect to its being brought into circulation
+     * Note: mandatory property according to EU Machine Directive
+     * 2006/42/EC.
+	 * @return
+	 */
+	@SuppressWarnings("unchecked")
+	public IMultiLanguageProperty getManufacturerName() {
+		return MultiLanguageProperty.createAsFacade((Map<String, Object>) getSubmodelElement(MANUFACTURERNAMEID));
+	}
+	
+	/**
+	 * Sets Short description of the product (short text)
+	 * Note: mandatory property according to EU Machine Directive
+	 * 2006/42/EC.
+	 * @param manufacturerProductDesignation {@link MultiLanguageProperty}
+	 */
+	public void setManufacturerProductDesignation(MultiLanguageProperty manufacturerProductDesignation) {
+		addSubmodelElement(manufacturerProductDesignation);
+	}
+	
+	/**
+	 * Sets Short description of the product (short text)
+	 * Note: mandatory property according to EU Machine Directive
+	 * 2006/42/EC.
+	 * @param manufacturerProductDesignation {@link LangString}
+	 */
+	public void setManufacturerProductDesignation(LangString manufacturerProductDesignation) {
+		MultiLanguageProperty manufacturerProductDesignationProp = new MultiLanguageProperty(MANUFACTURERPRODUCTDESIGNATIONID);
+		manufacturerProductDesignationProp.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "0173-1#02-AAW338#001", IdentifierType.IRDI)));
+		manufacturerProductDesignationProp.setValue(new LangStrings(manufacturerProductDesignation));
+		setManufacturerProductDesignation(manufacturerProductDesignationProp);
+	}
+	
+	/**
+	 * Gets Short description of the product (short text)
+	 * Note: mandatory property according to EU Machine Directive
+	 * 2006/42/EC.
+	 * @return
+	 */
+	@SuppressWarnings("unchecked")
+	public IMultiLanguageProperty getManufacturerProductDesignation() {
+		return MultiLanguageProperty.createAsFacade((Map<String, Object>) getSubmodelElement(MANUFACTURERPRODUCTDESIGNATIONID));
+	}
+	
+	/**
+	 * Sets address information of a business partner
+	 * 
+	 * Note: mandatory property according to EU Machine Directive
+	 * 2006/42/EC.
+	 * @param address
+	 */
+	public void setAddress(Address address) {
+		addSubmodelElement(address);
+	}
+	
+	/**
+	 * Gets address information of a business partner
+	 * 
+	 * Note: mandatory property according to EU Machine Directive
+	 * 2006/42/EC.
+	 * @return
+	 */
+	@SuppressWarnings("unchecked")
+	public Address getAddress() {
+		ISubmodelElement element = getSubmodelElement(ADDRESSID);
+		return element == null ? null : Address.createAsFacade((Map<String, Object>) element);
+	}
+	
+	/**
+	 * Sets 2nd level of a 3 level manufacturer specific product hierarchy
+	 * Note: mandatory property according to EU Machine Directive
+	 * 2006/42/EC.
+	 * @param manufacturerProductFamily {@link MultiLanguageProperty}
+	 */
+	public void setManufacturerProductFamily(MultiLanguageProperty manufacturerProductFamily) {
+		addSubmodelElement(manufacturerProductFamily);
+	}
+	
+	/**
+	 * Sets 2nd level of a 3 level manufacturer specific product hierarchy
+	 * Note: mandatory property according to EU Machine Directive
+	 * 2006/42/EC.
+	 * @param manufacturerProductFamily {@link LangString}
+	 */
+	public void setManufacturerProductFamily(LangString manufacturerProductFamily) {
+		MultiLanguageProperty manufacturerProductFamilyProp = new MultiLanguageProperty(MANUFACTURERPRODUCTFAMILYID);
+		manufacturerProductFamilyProp.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "0173-1#02-AAU731#001", IdentifierType.IRDI)));
+		manufacturerProductFamilyProp.setValue(new LangStrings(manufacturerProductFamily));
+		setManufacturerProductFamily(manufacturerProductFamilyProp);
+	}
+	
+	/**
+	 * Gets 2nd level of a 3 level manufacturer specific product hierarchy
+	 * Note: mandatory property according to EU Machine Directive
+	 * 2006/42/EC.
+	 * @return
+	 */
+	@SuppressWarnings("unchecked")
+	public IMultiLanguageProperty getManufacturerProductFamily() {
+		return MultiLanguageProperty.createAsFacade((Map<String, Object>) getSubmodelElement(MANUFACTURERPRODUCTFAMILYID));
+	}
+	
+	/**
+	 * Sets unique combination of numbers and letters used to identify the device
+	 * once it has been manufactured
+	 * @param serialNumber
+	 */
+	public void setSerialNumber(Property serialNumber) {
+		addSubmodelElement(serialNumber);
+	}
+	
+	/**
+	 * Sets unique combination of numbers and letters used to identify the device
+	 * once it has been manufactured
+	 * @param serialNumber
+	 */
+	public void setSerialNumber(String serialNumber) {
+		Property serialNumberProp = new Property(SERIALNUMBERID, ValueType.String);
+		serialNumberProp.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "0173-1#02-AAM556#002", IdentifierType.IRDI)));
+		serialNumberProp.setValue(serialNumber);
+		setSerialNumber(serialNumberProp);
+	}
+	
+	/**
+	 * Gets unique combination of numbers and letters used to identify the device
+	 * once it has been manufactured
+	 * @return
+	 */
+	@SuppressWarnings("unchecked")
+	public IProperty getSerialNumber() {
+		return Property.createAsFacade((Map<String, Object>) getSubmodelElement(SERIALNUMBERID));
+	}
+	
+	/**
+	 * Sets year as completion date of object
+	 * Note: mandatory property according to EU Machine Directive 2006/42/EC.
+	 * @param yearsOfConstruction
+	 */
+	public void setYearOfConstruction(Property yearsOfConstruction) {
+		addSubmodelElement(yearsOfConstruction);
+	}
+	
+	/**
+	 * Sets year as completion date of object
+	 * Note: mandatory property according to EU Machine Directive 2006/42/EC.
+	 * @param yearsOfConstruction
+	 */
+	public void setYearOfConstruction(String yearsOfConstruction) {
+		Property yearsOfConstructionProp = new Property(YEARSOFCONSTRUCTIONID, ValueType.String);
+		yearsOfConstructionProp.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "0173-1#02-AAP906#001", IdentifierType.IRDI)));
+		yearsOfConstructionProp.setValue(yearsOfConstruction);
+		setYearOfConstruction(yearsOfConstructionProp);
+	}
+	
+	/**
+	 * Gets year as completion date of object
+	 * Note: mandatory property according to EU Machine Directive 2006/42/EC.
+	 * @return
+	 */
+	@SuppressWarnings("unchecked")
+	public IProperty getYearOfConstruction() {
+		return Property.createAsFacade((Map<String, Object>) getSubmodelElement(YEARSOFCONSTRUCTIONID));
+	}
+	
+	/**
+	 * Sets collection of product markings
+	 * Note: CE marking is declared as mandatory according to EU Machine
+	 * Directive 2006/42/EC.
+	 * @param markings
+	 */
+	public void setMarkings(Markings markings) {
+		addSubmodelElement(markings);
+	}
+	
+	/**
+	 * Gets collection of product markings
+	 * Note: CE marking is declared as mandatory according to EU Machine
+	 * Directive 2006/42/EC.
+	 * @return
+	 */
+	@SuppressWarnings("unchecked")
+	public Markings getMarkings() {
+		ISubmodelElement element = getSubmodelElement(MARKINGSID);
+		return element == null ? null : Markings.createAsFacade((Map<String, Object>) element);
+	}
+	
+	/**
+	 * Sets collection of guideline specific properties
+	 * @param assetSpecificProperties
+	 */
+	public void setAssetSpecificProperties(AssetSpecificProperties assetSpecificProperties) {
+		addSubmodelElement(assetSpecificProperties);
+	}
+	
+	/**
+	 * Gets collection of guideline specific properties
+	 * @return
+	 */
+	@SuppressWarnings("unchecked")
+	public AssetSpecificProperties getAssetSpecificProperties() {
+		ISubmodelElement element = getSubmodelElement(ASSETSPECIFICPROPERTIESID);
+		return element == null ? null : AssetSpecificProperties.createAsFacade((Map<String, Object>) element);
+	}
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/enums/FaxType.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/enums/FaxType.java
new file mode 100644
index 0000000..74e8074
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/enums/FaxType.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.types.digitalnameplate.enums;
+
+import org.eclipse.basyx.submodel.metamodel.enumhelper.StandardizedLiteralEnum;
+import org.eclipse.basyx.submodel.metamodel.enumhelper.StandardizedLiteralEnumHelper;
+
+/**
+ * characterization of the fax according its location or usage
+ * as described in the AAS Digital Nameplate template
+ * @author haque
+ *
+ */
+public enum FaxType implements StandardizedLiteralEnum  {
+	
+	/**
+	 * (office, 0173-1#07-AAS754#001)
+	 */
+	OFFICE("1"),
+	
+	/**
+	 * (secretary, 0173-1#07-AAS756#001)
+	 */
+	SECRETARY("3"),
+	
+	/**
+	 * (home, 0173-1#07-AAS758#001)
+	 */
+	HOME("5");
+
+	private String standardizedLiteral;
+
+	private FaxType(String standardizedLiteral) {
+		this.standardizedLiteral = standardizedLiteral;
+	}
+
+	@Override
+	public String getStandardizedLiteral() {
+		return standardizedLiteral;
+	}
+
+	@Override
+	public String toString() {
+		return standardizedLiteral;
+	}
+
+	public static FaxType fromString(String str) {
+		return StandardizedLiteralEnumHelper.fromLiteral(FaxType.class, str);
+	}
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/enums/MailType.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/enums/MailType.java
new file mode 100644
index 0000000..9a6b1b6
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/enums/MailType.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.types.digitalnameplate.enums;
+
+import org.eclipse.basyx.submodel.metamodel.enumhelper.StandardizedLiteralEnum;
+import org.eclipse.basyx.submodel.metamodel.enumhelper.StandardizedLiteralEnumHelper;
+
+/**
+ * characterization of an e-mail address according to its location or usage
+ * as described in the AAS Digital Nameplate template
+ * @author haque
+ *
+ */
+public enum MailType implements StandardizedLiteralEnum {
+	// Enum values
+	
+	/**
+	 * (office, 0173-1#07-AAS754#001)
+	 */
+	OFFICE("1"),
+	
+	/**
+	 * (secretary, 0173-1#07-AAS756#001)
+	 */
+	SECRETARY("3"),
+	
+	/**
+	 * (substitute, 0173-1#07-AAS757#001)
+	 */
+	SUBSTITUTE("4"),
+	
+	/**
+	 * (home, 0173-1#07-AAS758#001)
+	 */
+	HOME("5");
+
+	private String standardizedLiteral;
+
+	private MailType(String standardizedLiteral) {
+		this.standardizedLiteral = standardizedLiteral;
+	}
+
+	@Override
+	public String getStandardizedLiteral() {
+		return standardizedLiteral;
+	}
+
+	@Override
+	public String toString() {
+		return standardizedLiteral;
+	}
+
+	public static MailType fromString(String str) {
+		return StandardizedLiteralEnumHelper.fromLiteral(MailType.class, str);
+	}
+
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/enums/PhoneType.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/enums/PhoneType.java
new file mode 100644
index 0000000..b588eae
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/enums/PhoneType.java
@@ -0,0 +1,72 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.types.digitalnameplate.enums;
+
+import org.eclipse.basyx.submodel.metamodel.enumhelper.StandardizedLiteralEnum;
+import org.eclipse.basyx.submodel.metamodel.enumhelper.StandardizedLiteralEnumHelper;
+
+/**
+ * characterization of a telephone according to its location or usage
+ * as described in the AAS Digital Nameplate template
+ * @author haque
+ *
+ */
+public enum PhoneType implements StandardizedLiteralEnum {
+	
+	/**
+	 * (office, 0173-1#07-AAS754#001)
+	 */
+	OFFICE("1"),
+	
+	/**
+	 * (office mobile, 0173-1#07-AAS755#001)
+	 */
+	OFFICEMOBILE("2"),
+	
+	/**
+	 * (secretary, 0173-1#07-AAS756#001)
+	 */
+	SECRETARY("3"),
+	
+	/**
+	 * (substitute, 0173-1#07-AAS757#001)
+	 */
+	SUBSTITUTE("4"),
+	
+	/**
+	 * (home, 0173-1#07-AAS758#001)
+	 */
+	HOME("5"),
+	
+	/**
+	 * (private mobile, 0173-1#07-AAS759#001)
+	 */
+	PRIVATEMOBILE("6");;
+
+	private String standardizedLiteral;
+
+	private PhoneType(String standardizedLiteral) {
+		this.standardizedLiteral = standardizedLiteral;
+	}
+
+	@Override
+	public String getStandardizedLiteral() {
+		return standardizedLiteral;
+	}
+
+	@Override
+	public String toString() {
+		return standardizedLiteral;
+	}
+
+	public static PhoneType fromString(String str) {
+		return StandardizedLiteralEnumHelper.fromLiteral(PhoneType.class, str);
+	}
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/address/Address.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/address/Address.java
new file mode 100644
index 0000000..d0ebd78
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/address/Address.java
@@ -0,0 +1,578 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.types.digitalnameplate.submodelelementcollections.address;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyType;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IMultiLanguageProperty;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
+import org.eclipse.basyx.submodel.metamodel.facade.SubmodelElementMapCollectionConverter;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangString;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangStrings;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.MultiLanguageProperty;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.submodel.types.helper.SubmodelElementRetrievalHelper;
+
+/**
+ * Address as defined in the AAS Digital Nameplate Template document <br/>
+ * It is a submodel element collection which contains
+ * The standardized SMC Address contains information 
+ * about address of a partner within the value chain.
+ * 
+ * @author haque
+ *
+ */
+public class Address extends SubmodelElementCollection {
+	public static final String DEPARTMENTID = "Department";
+	public static final String STREETID = "Street";
+	public static final String ZIPCODEID = "Zipcode";
+	public static final String POBOXID = "POBox";
+	public static final String ZIPCODEOFPOBOXID = "ZipCodeOfPOBox";
+	public static final String CITYTOWNID = "CityTown";
+	public static final String STATECOUNTYID = "StateCounty";
+	public static final String NATIONALCODEID = "NationalCode";
+	public static final String VATNUMBERID = "VATNumber";
+	public static final String ADDRESSREMARKSID = "AddressRemarks";
+	public static final String ADDRESSOFADDITIONALLINKID = "AddressOfAdditionalLink";
+	public static final String PHONEPREFIX = "Phone";
+	public static final String FAXPREFIX = "Fax";
+	public static final String EMAILPREFIX = "Email";
+	public static final Reference SEMANTICID = new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "0173-1#02-AAQ832#005", KeyType.IRDI));
+	public static final String ADDRESSIDSHORT = "Address";
+	
+	private Address() {
+	}
+	
+	/**
+	 * Constructor with default idShort
+	 * @param street
+	 * @param zipCode
+	 * @param cityTown
+	 * @param nationalCode
+	 */
+	public Address(MultiLanguageProperty street, MultiLanguageProperty zipCode, MultiLanguageProperty cityTown, MultiLanguageProperty nationalCode) {
+		this(ADDRESSIDSHORT, street, zipCode, cityTown, nationalCode);
+	}
+	
+	/**
+	 * Constructor with default idShort
+	 * @param street
+	 * @param zipCode
+	 * @param cityTown
+	 * @param nationalCode
+	 */
+	public Address(LangString street, LangString zipCode, LangString cityTown, LangString nationalCode) {
+		this(ADDRESSIDSHORT, street, zipCode, cityTown, nationalCode);
+	}
+	
+	/**
+	 * Constructor with mandatory attributes
+	 * @param idShort
+	 * @param street
+	 * @param zipCode
+	 * @param cityTown
+	 * @param nationalCode
+	 */
+	public Address(String idShort, MultiLanguageProperty street, MultiLanguageProperty zipCode, MultiLanguageProperty cityTown, MultiLanguageProperty nationalCode) {
+		super(idShort);
+		setSemanticId(SEMANTICID);
+		setStreet(street);
+		setZipCode(zipCode);
+		setCityTown(cityTown);
+		setNationalCode(nationalCode);
+	}
+	
+	/**
+	 * Constructor with mandatory attributes
+	 * @param idShort
+	 * @param street
+	 * @param zipCode
+	 * @param cityTown
+	 * @param nationalCode
+	 */
+	public Address(String idShort, LangString street, LangString zipCode, LangString cityTown, LangString nationalCode) {
+		super(idShort);
+		setSemanticId(SEMANTICID);
+		setStreet(street);
+		setZipCode(zipCode);
+		setCityTown(cityTown);
+		setNationalCode(nationalCode);
+	}
+	
+	/**
+	 * Creates a Address SMC object from a map
+	 * 
+	 * @param obj a Address SMC object as raw map
+	 * @return a Address SMC object, that behaves like a facade for the given map
+	 */
+	public static Address createAsFacade(Map<String, Object> obj) {
+		if (obj == null) {
+			return null;
+		}
+		
+		if (!isValid(obj)) {
+			throw new MetamodelConstructionException(Address.class, obj);
+		}
+
+		Address address = new Address();
+		address.setMap(SubmodelElementMapCollectionConverter.mapToSmECollection(obj));
+		return address;
+	}
+	
+	/**
+	 * Creates a Address SMC object from a map without validation
+	 * 
+	 * @param obj a Address SMC object as raw map
+	 * @return a Address SMC object, that behaves like a facade for the given map
+	 */
+	private static Address createAsFacadeNonStrict(Map<String, Object> obj) {
+		if (obj == null) {
+			return null;
+		}
+
+		Address address = new Address();
+		address.setMap(SubmodelElementMapCollectionConverter.mapToSmECollection(obj));
+		return address;
+	}
+	
+	/**
+	 * Check whether all mandatory elements for Address SMC
+	 * exist in the map
+	 * 
+	 * @param obj
+	 * 
+	 * @return true/false
+	 */
+	@SuppressWarnings("unchecked")
+	public static boolean isValid(Map<String, Object> obj) {
+		Address address = createAsFacadeNonStrict(obj);
+		
+		return SubmodelElementCollection.isValid(obj)
+				&& MultiLanguageProperty.isValid((Map<String, Object>) address.getStreet())
+				&& MultiLanguageProperty.isValid((Map<String, Object>) address.getZipCode())
+				&& MultiLanguageProperty.isValid((Map<String, Object>) address.getCityTown())
+				&& MultiLanguageProperty.isValid((Map<String, Object>) address.getNationalCode());
+	}
+
+	/**
+	 * Gets administrative section within an organisation where a business partner is located
+	 * @return
+	 */
+	@SuppressWarnings("unchecked")
+	public IMultiLanguageProperty getDepartment() {
+		return MultiLanguageProperty.createAsFacade((Map<String, Object>) getSubmodelElement(DEPARTMENTID));
+	}
+
+	/**
+	 * Sets administrative section within an organisation where a business partner is located
+	 * @param department {@link MultiLanguageProperty}
+	 */
+	public void setDepartment(MultiLanguageProperty department) {
+		addSubmodelElement(department);
+	}
+	
+	/**
+	 * Sets administrative section within an organisation where a business partner is located
+	 * @param department {@link LangString}
+	 */
+	public void setDepartment(LangString department) {
+		MultiLanguageProperty deptProp = new MultiLanguageProperty(DEPARTMENTID);
+		deptProp.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "0173-1#02-AAO127#003", IdentifierType.IRDI)));
+		deptProp.setValue(new LangStrings(department));
+		setDepartment(deptProp);
+	}
+
+	/**
+	 * Gets street name and house number
+     * Note: mandatory property according to EU Machine Directive 2006/42/EC.
+	 * @return
+	 */
+	@SuppressWarnings("unchecked")
+	public IMultiLanguageProperty getStreet() {
+		return MultiLanguageProperty.createAsFacade((Map<String, Object>) getSubmodelElement(STREETID));
+	}
+
+	/**
+	 * Sets street name and house number
+     * Note: mandatory property according to EU Machine Directive 2006/42/EC.
+	 * @param street {@link MultiLanguageProperty}
+	 */
+	public void setStreet(MultiLanguageProperty street) {
+		addSubmodelElement(street);
+	}
+	
+	/**
+	 * Sets street name and house number
+     * Note: mandatory property according to EU Machine Directive 2006/42/EC.
+	 * @param street {@link LangString}
+	 */
+	public void setStreet(LangString street) {
+		MultiLanguageProperty streetProp = new MultiLanguageProperty(STREETID);
+		streetProp.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "0173-1#02-AAO128#002", IdentifierType.IRDI)));
+		streetProp.setValue(new LangStrings(street));
+		setStreet(streetProp);
+	}
+
+	/**
+	 * Gets ZIP code of address
+     * Note: mandatory property according to EU Machine Directive 2006/42/EC.
+	 * @return
+	 */
+	@SuppressWarnings("unchecked")
+	public IMultiLanguageProperty getZipCode() {
+		return MultiLanguageProperty.createAsFacade((Map<String, Object>) getSubmodelElement(ZIPCODEID));
+	}
+
+	/**
+	 * Sets ZIP code of address
+     * Note: mandatory property according to EU Machine Directive 2006/42/EC.
+	 * @param zipCode {@link MultiLanguageProperty}
+	 */
+	public void setZipCode(MultiLanguageProperty zipCode) {
+		addSubmodelElement(zipCode);
+	}
+	
+	/**
+	 * Sets ZIP code of address
+     * Note: mandatory property according to EU Machine Directive 2006/42/EC.
+	 * @param zipCode {@link LangString}
+	 */
+	public void setZipCode(LangString zipCode) {
+		MultiLanguageProperty zipCodeProp = new MultiLanguageProperty(ZIPCODEID);
+		zipCodeProp.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "0173-1#02-AAO129#002", IdentifierType.IRDI)));
+		zipCodeProp.setValue(new LangStrings(zipCode));
+		setZipCode(zipCodeProp);
+	}
+
+	/**
+	 * Gets P.O. box number
+	 * @return
+	 */
+	@SuppressWarnings("unchecked")
+	public IMultiLanguageProperty getPOBox() {
+		return MultiLanguageProperty.createAsFacade((Map<String, Object>) getSubmodelElement(POBOXID));
+	}
+
+	/**
+	 * Sets P.O. box number
+	 * @param poBox {@link MultiLanguageProperty}
+	 */
+	public void setPOBox(MultiLanguageProperty poBox) {
+		addSubmodelElement(poBox);
+	}
+	
+	/**
+	 * Sets P.O. box number
+	 * @param poBox {@link LangString}
+	 */
+	public void setPOBox(LangString poBox) {
+		MultiLanguageProperty poBoxProp = new MultiLanguageProperty(POBOXID);
+		poBoxProp.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "0173-1#02-AAO130#002", IdentifierType.IRDI)));
+		poBoxProp.setValue(new LangStrings(poBox));
+		setPOBox(poBoxProp);
+	}
+
+	/**
+	 * Gets ZIP code of P.O. box address
+	 * @return
+	 */
+	@SuppressWarnings("unchecked")
+	public IMultiLanguageProperty getZipCodeOfPOBox() {
+		return MultiLanguageProperty.createAsFacade((Map<String, Object>) getSubmodelElement(ZIPCODEOFPOBOXID));
+	}
+
+	/**
+	 * Sets ZIP code of P.O. box address
+	 * @param zipCodeOfPoBox {@link MultiLanguageProperty}
+	 */
+	public void setZipCodeOfPOBox(MultiLanguageProperty zipCodeOfPoBox) {
+		addSubmodelElement(zipCodeOfPoBox);
+	}
+	
+	/**
+	 * Sets ZIP code of P.O. box address
+	 * @param zipCodeOfPoBox {@link LangString}
+	 */
+	public void setZipCodeOfPOBox(LangString zipCodeOfPoBox) {
+		MultiLanguageProperty zipCodeOfPoBoxProp = new MultiLanguageProperty(ZIPCODEOFPOBOXID);
+		zipCodeOfPoBoxProp.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "0173-1#02-AAO131#002", IdentifierType.IRDI)));
+		zipCodeOfPoBoxProp.setValue(new LangStrings(zipCodeOfPoBox));
+		setZipCodeOfPOBox(zipCodeOfPoBoxProp);
+	}
+
+	/**
+	 * Gets town or city
+     * Note: mandatory property according to EU Machine Directive 2006/42/EC.
+	 * @return
+	 */
+	@SuppressWarnings("unchecked")
+	public IMultiLanguageProperty getCityTown() {
+		return MultiLanguageProperty.createAsFacade((Map<String, Object>) getSubmodelElement(CITYTOWNID));
+	}
+	
+	/**
+	 * Sets town or city
+     * Note: mandatory property according to EU Machine Directive 2006/42/EC.
+	 * @param cityTown {@link MultiLanguageProperty}
+	 */
+	public void setCityTown(MultiLanguageProperty cityTown) {
+		addSubmodelElement(cityTown);
+	}
+	
+	/**
+	 * Sets town or city
+     * Note: mandatory property according to EU Machine Directive 2006/42/EC.
+	 * @param cityTown {@link LangString}
+	 */
+	public void setCityTown(LangString cityTown) {
+		MultiLanguageProperty cityTownProp = new MultiLanguageProperty(CITYTOWNID);
+		cityTownProp.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "0173-1#02-AAO132#002", IdentifierType.IRDI)));
+		cityTownProp.setValue(new LangStrings(cityTown));
+		setCityTown(cityTownProp);
+	}
+
+	/**
+	 * Gets federal state a part of a state
+	 * @return
+	 */
+	@SuppressWarnings("unchecked")
+	public IMultiLanguageProperty getStateCounty() {
+		return MultiLanguageProperty.createAsFacade((Map<String, Object>) getSubmodelElement(STATECOUNTYID));
+	}
+
+	/**
+	 * Sets federal state a part of a state
+	 * @param stateCounty {@link MultiLanguageProperty}
+	 */
+	public void setStateCounty(MultiLanguageProperty stateCounty) {
+		addSubmodelElement(stateCounty);
+	}
+
+	/**
+	 * Sets federal state a part of a state
+	 * @param stateCounty {@link LangString}
+	 */
+	public void setStateCounty(LangString stateCounty) {
+		MultiLanguageProperty stateCountyProp = new MultiLanguageProperty(STATECOUNTYID);
+		stateCountyProp.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "0173-1#02-AAO133#002", IdentifierType.IRDI)));
+		stateCountyProp.setValue(new LangStrings(stateCounty));
+		setStateCounty(stateCountyProp);
+	}
+	
+	/**
+	 * Gets code of a country
+     * Note: Country codes defined accord. to DIN EN ISO 3166-1
+     * Note: mandatory property according to EU Machine Directive 2006/42/EC.
+	 * @return
+	 */
+	@SuppressWarnings("unchecked")
+	public IMultiLanguageProperty getNationalCode() {
+		return MultiLanguageProperty.createAsFacade((Map<String, Object>) getSubmodelElement(NATIONALCODEID));
+	}
+
+	/**
+	 * Sets code of a country
+     * Note: Country codes defined accord. to DIN EN ISO 3166-1
+     * Note: mandatory property according to EU Machine Directive 2006/42/EC.
+	 * @param nationalCode {@link MultiLanguageProperty}
+	 */
+	public void setNationalCode(MultiLanguageProperty nationalCode) {
+		addSubmodelElement(nationalCode);
+	}
+	
+	/**
+	 * Sets code of a country
+     * Note: Country codes defined accord. to DIN EN ISO 3166-1
+     * Note: mandatory property according to EU Machine Directive 2006/42/EC.
+	 * @param nationalCode {@link LangString}
+	 */
+	public void setNationalCode(LangString nationalCode) {
+		MultiLanguageProperty nationalCodeProp = new MultiLanguageProperty(NATIONALCODEID);
+		nationalCodeProp.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "0173-1#02-AAO134#002", IdentifierType.IRDI)));
+		nationalCodeProp.setValue(new LangStrings(nationalCode));
+		setNationalCode(nationalCodeProp);
+	}
+
+	/**
+	 * Gets VAT identification number of the business partner
+	 * @return
+	 */
+	@SuppressWarnings("unchecked")
+	public IMultiLanguageProperty getVatNumber() {
+		return MultiLanguageProperty.createAsFacade((Map<String, Object>) getSubmodelElement(VATNUMBERID));
+	}
+
+	/**
+	 * Sets VAT identification number of the business partner
+	 * @param vatNumber {@link MultiLanguageProperty}
+	 */
+	public void setVatNumber(MultiLanguageProperty vatNumber) {
+		addSubmodelElement(vatNumber);
+	}
+	
+	/**
+	 * Sets VAT identification number of the business partner
+	 * @param vatNumber {@link LangString}
+	 */
+	public void setVatNumber(LangString vatNumber) {
+		MultiLanguageProperty vatNumberProp = new MultiLanguageProperty(VATNUMBERID);
+		vatNumberProp.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "0173-1#02-AAO135#002", IdentifierType.IRDI)));
+		vatNumberProp.setValue(new LangStrings(vatNumber));
+		setVatNumber(vatNumberProp);
+	}
+
+	/**
+	 * Gets plain text characterizing address information for which there is no property
+	 * @return
+	 */
+	@SuppressWarnings("unchecked")
+	public IMultiLanguageProperty getAddressRemarks() {
+		return MultiLanguageProperty.createAsFacade((Map<String, Object>) getSubmodelElement(ADDRESSREMARKSID));
+	}
+
+	/**
+	 * Sets plain text characterizing address information for which there is no property
+	 * @param addressRemarks {@link MultiLanguageProperty}
+	 */
+	public void setAddressRemarks(MultiLanguageProperty addressRemarks) {
+		addSubmodelElement(addressRemarks);
+	}
+	
+	/**
+	 * Sets plain text characterizing address information for which there is no property
+	 * @param addressRemarks {@link LangString}
+	 */
+	public void setAddressRemarks(LangString addressRemarks) {
+		MultiLanguageProperty addressRemarksProp = new MultiLanguageProperty(ADDRESSREMARKSID);
+		addressRemarksProp.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "0173-1#02-AAO202#003", IdentifierType.IRDI)));
+		addressRemarksProp.setValue(new LangStrings(addressRemarks));
+		setAddressRemarks(addressRemarksProp);
+	}
+
+	/**
+	 * Gets web site address where information about the product or contact is given
+	 * @return
+	 */
+	@SuppressWarnings("unchecked")
+	public IProperty getAddressOfAdditionalLink() {
+		return Property.createAsFacade((Map<String, Object>) getSubmodelElement(ADDRESSOFADDITIONALLINKID));
+	}
+
+	/**
+	 * Sets web site address where information about the product or contact is given
+	 * @param addressOfAdditionalLink {@link Property}
+	 */
+	public void setAddressOfAdditionalLink(Property addressOfAdditionalLink) {
+		addSubmodelElement(addressOfAdditionalLink);
+	}
+	
+	/**
+	 * Sets web site address where information about the product or contact is given
+	 * @param addressOfAdditionalLink {@link String}
+	 */
+	public void setAddressOfAdditionalLink(String addressOfAdditionalLink) {
+		Property addressOfAdditionalLinkProp = new Property(ADDRESSOFADDITIONALLINKID, ValueType.String);
+		addressOfAdditionalLinkProp.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "0173-1#02-AAQ326#002", IdentifierType.IRDI)));
+		addressOfAdditionalLinkProp.setValue(addressOfAdditionalLink);
+		setAddressOfAdditionalLink(addressOfAdditionalLinkProp);
+	}
+
+	/**
+	 * Gets Phone number including type
+	 * @return
+	 */
+	@SuppressWarnings("unchecked")
+	public List<Phone> getPhone() {
+		List<Phone> ret = new ArrayList<Phone>();
+		List<ISubmodelElement> elements = SubmodelElementRetrievalHelper.getSubmodelElementsByIdPrefix(PHONEPREFIX, getSubmodelElements());
+		
+		for (ISubmodelElement element: elements) {
+			ret.add(Phone.createAsFacade((Map<String, Object>) element));
+		}
+		return ret;
+	}
+
+	/**
+	 * Sets Phone number including type
+	 * @param phone
+	 */
+	public void setPhone(List<Phone> phones) {
+		if (phones != null && phones.size() > 0) {
+			for (Phone phone : phones) {
+				addSubmodelElement(phone);
+			}
+		}
+	}
+
+	/**
+	 * Gets fax number including type
+	 * @return
+	 */
+	@SuppressWarnings("unchecked")
+	public List<Fax> getFax() {
+		List<Fax> ret = new ArrayList<Fax>();
+		List<ISubmodelElement> elements = SubmodelElementRetrievalHelper.getSubmodelElementsByIdPrefix(FAXPREFIX, getSubmodelElements());
+		
+		for (ISubmodelElement element: elements) {
+			ret.add(Fax.createAsFacade((Map<String, Object>) element));
+		}
+		return ret;
+	}
+
+	/**
+	 * Sets fax number including type
+	 * @param fax
+	 */
+	public void setFax(List<Fax> faxes) {
+		if (faxes != null && faxes.size() > 0) {
+			for (Fax fax : faxes) {
+				addSubmodelElement(fax);
+			}
+		}
+	}
+
+	/**
+	 * Gets E-mail address and encryption method
+	 * @return
+	 */
+	@SuppressWarnings("unchecked")
+	public List<Email> getEmail() {
+		List<Email> ret = new ArrayList<Email>();
+		List<ISubmodelElement> elements = SubmodelElementRetrievalHelper.getSubmodelElementsByIdPrefix(EMAILPREFIX, getSubmodelElements());
+		
+		for (ISubmodelElement element: elements) {
+			ret.add(Email.createAsFacade((Map<String, Object>) element));
+		}
+		return ret;
+	}
+
+	/**
+	 * Sets E-mail address and encryption method
+	 * @param email
+	 */
+	public void setEmail(List<Email> emails) {
+		if (emails != null && emails.size() > 0) {
+			for (Email email : emails) {
+				addSubmodelElement(email);
+			}
+		}
+	}
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/address/Email.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/address/Email.java
new file mode 100644
index 0000000..0f82b5a
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/address/Email.java
@@ -0,0 +1,236 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.types.digitalnameplate.submodelelementcollections.address;
+
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyType;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IMultiLanguageProperty;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
+import org.eclipse.basyx.submodel.metamodel.facade.SubmodelElementMapCollectionConverter;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangString;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangStrings;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.MultiLanguageProperty;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.submodel.types.digitalnameplate.enums.MailType;
+
+/**
+ * Email as defined in the AAS Digital Nameplate Template document <br/>
+ * It is a submodel element collection which contains email address and encryption method
+ * 
+ * @author haque
+ *
+ */
+public class Email extends SubmodelElementCollection {
+	public static final String EMAILADDRESSID = "EmailAddress";
+	public static final String PUBLICKEYID = "PublicKey";
+	public static final String TYPEOFEMAILADDRESSID = "TypeOfEmailAddress";
+	public static final String TYPEOFPUBLICKEYID = "TypeOfPublickKey";
+	public static final Reference SEMANTICID = new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "0173-1#02-AAQ836#005", KeyType.IRDI));
+	
+	private Email() {
+	}
+	
+	/**
+	 * Constructor with mandatory attributes
+	 * @param idShort
+	 * @param emailAddress
+	 */
+	public Email(String idShort, Property emailAddress) {
+		super(idShort);
+		setSemanticId(SEMANTICID);
+		setEmailAddress(emailAddress);
+	}
+	
+	/**
+	 * Constructor with mandatory attributes
+	 * @param idShort
+	 * @param emailAddress
+	 */
+	public Email(String idShort, String emailAddress) {
+		super(idShort);
+		setSemanticId(SEMANTICID);
+		setEmailAddress(emailAddress);
+	}
+	
+	/**
+	 * Creates a Email SMC object from a map
+	 * 
+	 * @param obj a Email SMC object as raw map
+	 * @return a Email SMC object, that behaves like a facade for the given map
+	 */
+	public static Email createAsFacade(Map<String, Object> obj) {
+		if (obj == null) {
+			return null;
+		}
+		
+		if (!isValid(obj)) {
+			throw new MetamodelConstructionException(Email.class, obj);
+		}
+		
+		Email email = new Email();
+		email.setMap(SubmodelElementMapCollectionConverter.mapToSmECollection(obj));
+		return email;
+	}
+	
+	/**
+	 * Creates a Email SMC object from a map without validation
+	 * 
+	 * @param obj a Email SMC object as raw map
+	 * @return a Email SMC object, that behaves like a facade for the given map
+	 */
+	private static Email createAsFacadeNonStrict(Map<String, Object> obj) {
+		if (obj == null) {
+			return null;
+		}
+		
+		Email email = new Email();
+		email.setMap(SubmodelElementMapCollectionConverter.mapToSmECollection(obj));
+		return email;
+	}
+	
+	/**
+	 * Check whether all mandatory elements for Email SMC
+	 * exist in the map
+	 * 
+	 * @param obj
+	 * 
+	 * @return true/false
+	 */
+	@SuppressWarnings("unchecked")
+	public static boolean isValid(Map<String, Object> obj) {
+		Email email = createAsFacadeNonStrict(obj);
+		
+		return SubmodelElementCollection.isValid(obj)
+				&& Property.isValid((Map<String, Object>) email.getEmailAddress());
+	}
+	
+	/**
+	 * Sets electronic mail address of a business partner
+	 * @param emailAddress Property
+	 */
+	public void setEmailAddress(Property emailAddress) {
+		addSubmodelElement(emailAddress);
+	}
+	
+	/**
+	 * Sets electronic mail address of a business partner
+	 * @param emailAddress String
+	 */
+	public void setEmailAddress(String emailAddress) {
+		Property emailProp = new Property(EMAILADDRESSID, ValueType.String);
+		emailProp.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "0173-1#02-AAO198#002", IdentifierType.IRDI)));
+		emailProp.setValue(emailAddress);
+		setEmailAddress(emailProp);
+	}
+	
+	/**
+	 * Gets electronic mail address of a business partner
+	 * @return
+	 */
+	@SuppressWarnings("unchecked")
+	public IProperty getEmailAddress() {
+		return Property.createAsFacade((Map<String, Object>) getSubmodelElement(EMAILADDRESSID));
+	}
+	
+	/**
+	 * Sets public part of an unsymmetrical key pair to sign or encrypt text or messages
+	 * @param key {@link MultiLanguageProperty}
+	 */
+	public void setPublicKey(MultiLanguageProperty key) {
+		addSubmodelElement(key);
+	}
+	
+	/**
+	 * Sets public part of an unsymmetrical key pair to sign or encrypt text or messages
+	 * @param key {@link LangString}
+	 */
+	public void setPublicKey(LangString key) {
+		MultiLanguageProperty publicKey = new MultiLanguageProperty(PUBLICKEYID);
+		publicKey.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "0173-1#02-AAO200#002", IdentifierType.IRDI)));
+		publicKey.setValue(new LangStrings(key));
+		setPublicKey(publicKey);
+	}
+	
+	/**
+	 * Gets public part of an unsymmetrical key pair to sign or encrypt text or messages
+	 * @return
+	 */
+	@SuppressWarnings("unchecked")
+	public IMultiLanguageProperty getPublicKey() {
+		return MultiLanguageProperty.createAsFacade((Map<String, Object>) getSubmodelElement(PUBLICKEYID));
+	}
+	
+	/**
+	 * Sets characterization of an e-mail address according to its location or usage
+	 * enumeration
+	 * @param type {@link Property}
+	 */
+	public void setTypeOfEmailAddress(Property type) {
+		addSubmodelElement(type);
+	}
+	
+	/**
+	 * Sets characterization of an e-mail address according to its location or usage
+	 * enumeration
+	 * @param type {@link MailType}
+	 */
+	public void setTypeOfEmailAddress(MailType type) {
+		Property mailTypeProp = new Property(TYPEOFEMAILADDRESSID, ValueType.String);
+		mailTypeProp.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "0173-1#02-AAO199#003", IdentifierType.IRDI)));
+		mailTypeProp.setValue(type.toString());
+		setTypeOfEmailAddress(mailTypeProp);
+	}
+	
+	/**
+	 * Gets characterization of an e-mail address according to its location or usage
+	 * enumeration
+	 * @return
+	 */
+	@SuppressWarnings("unchecked")
+	public IProperty getTypeOfEmailAddress() {
+		return Property.createAsFacade((Map<String, Object>) getSubmodelElement(TYPEOFEMAILADDRESSID));
+	}
+	
+	/**
+	 * Sets characterization of a public key according to its encryption process
+	 * @param key {@link MultiLanguageProperty}
+	 */
+	public void setTypeOfPublicKey(MultiLanguageProperty key) {
+		addSubmodelElement(key);
+	}
+	
+	/**
+	 * Sets characterization of a public key according to its encryption process
+	 * @param key {@link LangString}
+	 */
+	public void setTypeOfPublicKey(LangString key) {
+		MultiLanguageProperty typeOfPublicKey = new MultiLanguageProperty(TYPEOFPUBLICKEYID);
+		typeOfPublicKey.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "0173-1#02-AAO201#002", IdentifierType.IRDI)));
+		typeOfPublicKey.setValue(new LangStrings(key));
+		setTypeOfPublicKey(typeOfPublicKey);
+	}
+	
+	/**
+	 * Gets characterization of a public key according to its encryption process
+	 * @return
+	 */
+	@SuppressWarnings("unchecked")
+	public IMultiLanguageProperty getTypeOfPublicKey() {
+		return MultiLanguageProperty.createAsFacade((Map<String, Object>) getSubmodelElement(TYPEOFPUBLICKEYID));
+	}
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/address/Fax.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/address/Fax.java
new file mode 100644
index 0000000..5bcc9e5
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/address/Fax.java
@@ -0,0 +1,177 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.types.digitalnameplate.submodelelementcollections.address;
+
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyType;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IMultiLanguageProperty;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
+import org.eclipse.basyx.submodel.metamodel.facade.SubmodelElementMapCollectionConverter;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangString;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangStrings;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.MultiLanguageProperty;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.submodel.types.digitalnameplate.enums.FaxType;
+
+/**
+ * Fax as defined in the AAS Digital Nameplate Template document <br/>
+ * It is a submodel element collection which contains a fax number including type
+ * 
+ * @author haque
+ *
+ */
+public class Fax extends SubmodelElementCollection {
+	public static final String FAXNUMBERID = "FaxNumber";
+	public static final String TYPEOFFAXID = "TypeOfFaxNumber";
+	public static final Reference SEMANTICID = new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "0173-1#02-AAQ834#005", KeyType.IRDI));
+	
+	private Fax() {
+	}
+	
+	/**
+	 * Constructor with mandatory attributes
+	 * @param idShort
+	 * @param faxNumber
+	 */
+	public Fax(String idShort, LangString faxNumber) {
+		super(idShort);
+		setSemanticId(SEMANTICID);
+		setFaxNumber(faxNumber);
+	}
+	
+	/**
+	 * Constructor with mandatory attributes
+	 * @param idShort
+	 * @param faxNumber
+	 */
+	public Fax(String idShort, MultiLanguageProperty faxNumber) {
+		super(idShort);
+		setSemanticId(SEMANTICID);
+		setFaxNumber(faxNumber);
+	}
+	
+	/**
+	 * Creates a Fax SMC object from a map
+	 * 
+	 * @param obj a Fax SMC object as raw map
+	 * @return a Fax SMC object, that behaves like a facade for the given map
+	 */
+	public static Fax createAsFacade(Map<String, Object> obj) {
+		if (obj == null) {
+			return null;
+		}
+		
+		if (!isValid(obj)) {
+			throw new MetamodelConstructionException(Fax.class, obj);
+		}
+		
+		Fax fax = new Fax();
+		fax.setMap(SubmodelElementMapCollectionConverter.mapToSmECollection(obj));
+		return fax;
+	}
+	
+	/**
+	 * Creates a Fax SMC object from a map without validation
+	 * 
+	 * @param obj a Fax SMC object as raw map
+	 * @return a Fax SMC object, that behaves like a facade for the given map
+	 */
+	private static Fax createAsFacadeNonStrict(Map<String, Object> obj) {
+		if (obj == null) {
+			return null;
+		}
+		
+		Fax fax = new Fax();
+		fax.setMap(SubmodelElementMapCollectionConverter.mapToSmECollection(obj));
+		return fax;
+	}
+	
+	/**
+	 * Check whether all mandatory elements for Fax SMC
+	 * exist in the map
+	 * 
+	 * @param obj
+	 * 
+	 * @return true/false
+	 */
+	@SuppressWarnings("unchecked")
+	public static boolean isValid(Map<String, Object> obj) {
+		Fax fax = createAsFacadeNonStrict(obj);
+		return SubmodelElementCollection.isValid(obj)
+				&& MultiLanguageProperty.isValid((Map<String, Object>) fax.getFaxNumber());
+	}
+	
+	/**
+	 * Sets complete telephone number to be called to reach a 
+	 * business partner's fax machine
+	 * @param faxNumber {@link MultiLanguageProperty}
+	 */
+	public void setFaxNumber(MultiLanguageProperty faxNumber) {
+		addSubmodelElement(faxNumber);
+	}
+	
+	/**
+	 * Sets complete telephone number to be called to reach a 
+	 * business partner's fax machine
+	 * @param faxNumber {@link LangString}
+	 */
+	public void setFaxNumber(LangString faxNumber) {
+		MultiLanguageProperty faxProp = new MultiLanguageProperty(FAXNUMBERID);
+		faxProp.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "0173-1#02-AAO195#002", IdentifierType.IRDI)));
+		faxProp.setValue(new LangStrings(faxNumber));
+		setFaxNumber(faxProp);
+	}
+	
+	/**
+	 * Sets characterization of the fax according its location or usage
+	 * @param type {@link Property}
+	 */
+	public void setTypeOfFaxNumber(Property type) {
+		addSubmodelElement(type);
+	}
+	
+	/**
+	 * Sets characterization of the fax according its location or usage
+	 * @param type {@link FaxType}
+	 */
+	public void setTypeOfFaxNumber(FaxType type) {
+		Property faxTypeProp = new Property(TYPEOFFAXID, ValueType.String);
+		faxTypeProp.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "0173-1#02-AAO196#003", IdentifierType.IRDI)));
+		faxTypeProp.setValue(type.toString());
+		setTypeOfFaxNumber(faxTypeProp);
+	}
+	
+	/**
+	 * Gets characterization of the fax according its location or usage
+	 * @return
+	 */
+	@SuppressWarnings("unchecked")
+	public IProperty getTypeOfFaxNumber() {
+		return Property.createAsFacade((Map<String, Object>) getSubmodelElement(TYPEOFFAXID));
+	}
+	
+	/**
+	 * Gets complete telephone number to be called to reach a 
+	 * business partner's fax machine
+	 * @return
+	 */
+	@SuppressWarnings("unchecked")
+	public IMultiLanguageProperty getFaxNumber() {
+		return MultiLanguageProperty.createAsFacade((Map<String, Object>) getSubmodelElement(FAXNUMBERID));
+	}
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/address/Phone.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/address/Phone.java
new file mode 100644
index 0000000..7ee01f2
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/address/Phone.java
@@ -0,0 +1,175 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.types.digitalnameplate.submodelelementcollections.address;
+
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyType;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IMultiLanguageProperty;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
+import org.eclipse.basyx.submodel.metamodel.facade.SubmodelElementMapCollectionConverter;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangString;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangStrings;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.MultiLanguageProperty;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.submodel.types.digitalnameplate.enums.PhoneType;
+
+/**
+ * Phone as defined in the AAS Digital Nameplate Template document <br/>
+ * It is a submodel element collection which contains a phone number including type
+ * 
+ * @author haque
+ *
+ */
+public class Phone extends SubmodelElementCollection {
+	public static final String TELEPHONENUMBERID = "TelephoneNumber";
+	public static final String TYPEOFTELEPHONEID = "TypeOfTelephone";
+	public static final String PHONEID = "Phone";
+	public static final Reference SEMANTICID = new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "0173-1#02-AAQ833#005", KeyType.IRDI));
+	
+	private Phone() {}
+	
+	/**
+	 * Constructor with mandatory attributes
+	 * @param idShort
+	 * @param telephoneNumber
+	 */
+	public Phone(String idShort, LangString telephoneNumber) {
+		super(idShort);
+		setSemanticId(SEMANTICID);
+		setTelephoneNumber(telephoneNumber);
+	}
+	
+	/**
+	 * Constructor with mandatory attributes
+	 * @param idShort
+	 * @param telephoneNumber
+	 */
+	public Phone(String idShort, MultiLanguageProperty telephoneNumber) {
+		super(idShort);
+		setSemanticId(SEMANTICID);
+		setTelephoneNumber(telephoneNumber);
+	}
+	
+	/**
+	 * Creates a Phone SMC object from a map
+	 * 
+	 * @param obj a Phone SMC object as raw map
+	 * @return a Phone SMC object, that behaves like a facade for the given map
+	 */
+	public static Phone createAsFacade(Map<String, Object> obj) {
+		if (obj == null) {
+			return null;
+		}
+		
+		if (!isValid(obj)) {
+			throw new MetamodelConstructionException(Phone.class, obj);
+		}
+		
+		Phone phone = new Phone();
+		phone.setMap(SubmodelElementMapCollectionConverter.mapToSmECollection(obj));
+		return phone;
+	}
+	
+	/**
+	 * Creates a Phone SMC object from a map without checking validity
+	 * 
+	 * @param obj a Phone SMC object as raw map
+	 * @return a Phone SMC object, that behaves like a facade for the given map
+	 */
+	private static Phone createAsFacadeNonStrict(Map<String, Object> obj) {
+		if (obj == null) {
+			return null;
+		}
+		
+		Phone phone = new Phone();
+		phone.setMap(SubmodelElementMapCollectionConverter.mapToSmECollection(obj));
+		return phone;
+	}
+	
+	/**
+	 * Check whether all mandatory elements for Phone SMC
+	 * exist in the map
+	 * 
+	 * @param obj
+	 * 
+	 * @return true/false
+	 */
+	@SuppressWarnings("unchecked")
+	public static boolean isValid(Map<String, Object> obj) {
+		Phone phone = createAsFacadeNonStrict(obj);
+		
+		return SubmodelElementCollection.isValid(obj)
+				&& MultiLanguageProperty.isValid((Map<String, Object>) phone.getTelephoneNumber());
+	}
+	
+	/**
+	 * Sets complete telephone number to be called to reach a business partner
+	 * @param telephoneNumber {@link MultiLanguageProperty}
+	 */
+	public void setTelephoneNumber(MultiLanguageProperty telephoneNumber) {
+		addSubmodelElement(telephoneNumber);
+	}
+	
+	/**
+	 * Sets complete telephone number to be called to reach a business partner
+	 * @param telephoneNumber {@link LangString}
+	 */
+	public void setTelephoneNumber(LangString telephoneNumber) {
+		MultiLanguageProperty phoneProp = new MultiLanguageProperty(TELEPHONENUMBERID);
+		phoneProp.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "0173-1#02-AAO136#002", IdentifierType.IRDI)));
+		phoneProp.setValue(new LangStrings(telephoneNumber));
+		setTelephoneNumber(phoneProp);
+	}
+	
+	/**
+	 * Sets characterization of a telephone according to its location or usage enumeration
+	 * @param type {@link Property}
+	 */
+	public void setTypeOfTelephone(Property type) {
+		addSubmodelElement(type);
+	}
+	
+	/**
+	 * Sets characterization of a telephone according to its location or usage enumeration
+	 * @param type {@link PhoneType}
+	 */
+	public void setTypeOfTelephone(PhoneType type) {
+		Property phoneTypeProp = new Property(TYPEOFTELEPHONEID, ValueType.String);
+		phoneTypeProp.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "0173-1#02-AAO137#003", IdentifierType.IRDI)));
+		phoneTypeProp.setValue(type.toString());
+		setTypeOfTelephone(phoneTypeProp);
+	}
+	
+	/**
+	 * Gets characterization of a telephone according to its location or usage enumeration
+	 * @return
+	 */
+	@SuppressWarnings("unchecked")
+	public IProperty getTypeOfTelephone() {
+		return Property.createAsFacade((Map<String, Object>) getSubmodelElement(TYPEOFTELEPHONEID));
+	}
+	
+	/**
+	 * Gets complete telephone number to be called to reach a business partner
+	 * @return
+	 */
+	@SuppressWarnings("unchecked")
+	public IMultiLanguageProperty getTelephoneNumber() {
+		return MultiLanguageProperty.createAsFacade((Map<String, Object>) getSubmodelElement(TELEPHONENUMBERID));
+	}
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/assetspecificproperties/AssetSpecificProperties.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/assetspecificproperties/AssetSpecificProperties.java
new file mode 100644
index 0000000..03f504d
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/assetspecificproperties/AssetSpecificProperties.java
@@ -0,0 +1,140 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.types.digitalnameplate.submodelelementcollections.assetspecificproperties;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyType;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.facade.SubmodelElementMapCollectionConverter;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
+import org.eclipse.basyx.submodel.types.helper.SubmodelElementRetrievalHelper;
+
+/**
+ * AssetSpecificProperties as defined in the AAS Digital Nameplate Template document <br/>
+ * It is a submodel element collection which contains collection of guideline specific properties
+ * 
+ * @author haque
+ *
+ */
+public class AssetSpecificProperties extends SubmodelElementCollection {
+	public static final String ASSETSPECIFICPROPERTIESID = "AssetSpecificProperties";
+	public static final String GUIDELINESPECIFICPROPERTYPREFIX = "GuidelineSpecificProperties";
+	public static final Reference SEMANTICID = new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "https://admin-shell.io/zvei/nameplate/1/0/Nameplate/AssetSpecificProperties", KeyType.IRI));
+	
+	private AssetSpecificProperties() {
+	}
+	
+	/**
+	 * Constructor with default idShort
+	 * @param guidelineSpecificProperties
+	 */
+	public AssetSpecificProperties(List<GuidelineSpecificProperties> guidelineSpecificProperties) {
+		this (ASSETSPECIFICPROPERTIESID, guidelineSpecificProperties);
+	}
+	
+	/**
+	 * Constructor with mandatory attributes
+	 * 
+	 * @param idShort
+	 * @param guidelineSpecificProperties
+	 */
+	public AssetSpecificProperties(String idShort, List<GuidelineSpecificProperties> guidelineSpecificProperties) {
+		super(idShort);
+		setSemanticId(SEMANTICID);
+		setGuidelineSpecificProperties(guidelineSpecificProperties);
+	}
+	
+	/**
+	 * Creates a AssetSpecificProperties SMC object from a map
+	 * 
+	 * @param obj a AssetSpecificProperties SMC object as raw map
+	 * @return a AssetSpecificProperties SMC object, that behaves like a facade for the given map
+	 */
+	public static AssetSpecificProperties createAsFacade(Map<String, Object> obj) {
+		if (obj == null) {
+			return null;
+		}
+		
+		if (!isValid(obj)) {
+			throw new MetamodelConstructionException(AssetSpecificProperties.class, obj);
+		}
+		
+		AssetSpecificProperties assetSpecificProperties = new AssetSpecificProperties();
+		assetSpecificProperties.setMap((Map<String, Object>)SubmodelElementMapCollectionConverter.mapToSmECollection(obj));
+		return assetSpecificProperties;
+	}
+	
+	/**
+	 * Creates a AssetSpecificProperties SMC object from a map without validation
+	 * 
+	 * @param obj a AssetSpecificProperties SMC object as raw map
+	 * @return a AssetSpecificProperties SMC object, that behaves like a facade for the given map
+	 */
+	private static AssetSpecificProperties createAsFacadeNonStrict(Map<String, Object> obj) {
+		if (obj == null) {
+			return null;
+		}
+		
+		AssetSpecificProperties assetSpecificProperties = new AssetSpecificProperties();
+		assetSpecificProperties.setMap((Map<String, Object>)SubmodelElementMapCollectionConverter.mapToSmECollection(obj));
+		return assetSpecificProperties;
+	}
+	
+	/**
+	 * Check whether all mandatory elements for AssetSpecificProperties SMC
+	 * exist in the map
+	 * 
+	 * @param obj
+	 * 
+	 * @return true/false
+	 */
+	public static boolean isValid(Map<String, Object> obj) {
+		AssetSpecificProperties props = createAsFacadeNonStrict(obj);
+		
+		if (SubmodelElementCollection.isValid(obj)
+				&& props.getGuidelineSpecificProperties() != null
+				&& props.getGuidelineSpecificProperties().size() > 0) {
+			for (GuidelineSpecificProperties prop : props.getGuidelineSpecificProperties()) {
+				if (!GuidelineSpecificProperties.isValid((Map<String, Object>) prop)) {
+					return false;
+				}
+			}
+			return true;
+		} else {
+			return false;	
+		}
+	}
+	
+	public void setGuidelineSpecificProperties(List<GuidelineSpecificProperties> properties) {
+		if (properties != null & properties.size() > 0) {
+			for (GuidelineSpecificProperties prop : properties) {
+				addSubmodelElement(prop);
+			}
+		}
+	}
+
+	@SuppressWarnings("unchecked")
+	public List<GuidelineSpecificProperties> getGuidelineSpecificProperties() {
+		List<GuidelineSpecificProperties> ret = new ArrayList<GuidelineSpecificProperties>();
+		List<ISubmodelElement> elements = SubmodelElementRetrievalHelper.getSubmodelElementsByIdPrefix(GUIDELINESPECIFICPROPERTYPREFIX, getSubmodelElements());
+		
+		for (ISubmodelElement element: elements) {
+			ret.add(GuidelineSpecificProperties.createAsFacade((Map<String, Object>) element));
+		}
+		return ret;
+	}
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/assetspecificproperties/GuidelineSpecificProperties.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/assetspecificproperties/GuidelineSpecificProperties.java
new file mode 100644
index 0000000..b60d5a1
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/assetspecificproperties/GuidelineSpecificProperties.java
@@ -0,0 +1,195 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.types.digitalnameplate.submodelelementcollections.assetspecificproperties;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyType;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
+import org.eclipse.basyx.submodel.metamodel.facade.SubmodelElementMapCollectionConverter;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+
+/**
+ * GuidelineSpecificProperties as defined in the AAS Digital Nameplate Template document <br/>
+ * It is a submodel element collection which contains Asset specific nameplate 
+ * information required by guideline, stipulation or legislation.
+ * 
+ * @author haque
+ *
+ */
+public class GuidelineSpecificProperties extends SubmodelElementCollection {
+	public static final String GUIDELINEFORCONFORMITYDECLARATIONID = "GuidelineForConformityDeclaration";
+	public static final Reference SEMANTICID = new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "https://adminshell.io/zvei/nameplate/1/0/Nameplate/AssetSpecificProperties/GuidelineSpecificProperties", KeyType.IRI));
+	
+	private GuidelineSpecificProperties() {
+	}
+	
+	/**
+	 * Constructor with mandatory attributes
+	 * 
+	 * @param idShort
+	 * @param declaration
+	 * @param arbitrary
+	 */
+	public GuidelineSpecificProperties(String idShort, Property declaration, List<Property> arbitrary) {
+		super(idShort);
+		setSemanticId(SEMANTICID);
+		setGuidelineForConformityDeclaration(declaration);
+		setArbitrary(arbitrary);
+	}
+	
+	/**
+	 * Constructor with mandatory attributes
+	 * 
+	 * @param idShort
+	 * @param declaration
+	 * @param arbitrary
+	 */
+	public GuidelineSpecificProperties(String idShort, String declaration, List<Property> arbitrary) {
+		super(idShort);
+		setSemanticId(SEMANTICID);
+		setGuidelineForConformityDeclaration(declaration);
+		setArbitrary(arbitrary);
+	}
+	
+	/**
+	 * Creates a GuidelineSpecificProperties SMC object from a map
+	 * 
+	 * @param obj a GuidelineSpecificProperties SMC object as raw map
+	 * @return a GuidelineSpecificProperties SMC object, that behaves like a facade for the given map
+	 */
+	public static GuidelineSpecificProperties createAsFacade(Map<String, Object> obj) {
+		if (obj == null) {
+			return null;
+		}
+		
+		if (!isValid(obj)) {
+			throw new MetamodelConstructionException(GuidelineSpecificProperties.class, obj);
+		}
+		
+		GuidelineSpecificProperties guidelineSpecificProperties = new GuidelineSpecificProperties();
+		guidelineSpecificProperties.setMap(SubmodelElementMapCollectionConverter.mapToSmECollection(obj));
+		return guidelineSpecificProperties;
+	}
+	
+	/**
+	 * Creates a GuidelineSpecificProperties SMC object from a map without validation
+	 * 
+	 * @param obj a GuidelineSpecificProperties SMC object as raw map
+	 * @return a GuidelineSpecificProperties SMC object, that behaves like a facade for the given map
+	 */
+	private static GuidelineSpecificProperties createAsFacadeNonStrict(Map<String, Object> obj) {
+		if (obj == null) {
+			return null;
+		}
+		
+		GuidelineSpecificProperties guidelineSpecificProperties = new GuidelineSpecificProperties();
+		guidelineSpecificProperties.setMap(SubmodelElementMapCollectionConverter.mapToSmECollection(obj));
+		return guidelineSpecificProperties;
+	}
+	
+	/**
+	 * Check whether all mandatory elements for GuidelineSpecificProperties SMC
+	 * exist in the map
+	 * 
+	 * @param obj
+	 * 
+	 * @return true/false
+	 */
+	@SuppressWarnings("unchecked")
+	public static boolean isValid(Map<String, Object> obj) {
+		GuidelineSpecificProperties props = createAsFacadeNonStrict(obj);
+		
+		if (SubmodelElementCollection.isValid(obj)
+				&& Property.isValid((Map<String, Object>) props.getGuidelineForConformityDeclaration())
+				&& props.getArbitrary() != null
+				&& props.getArbitrary().size() > 0) {
+			for (IProperty arbitrary: props.getArbitrary()) {
+				if (!Property.isValid((Map<String, Object>) arbitrary)) {
+					return false;
+				}	
+			}
+			return true;
+		}
+		else {
+			return false;	
+		}
+	}
+	
+	/**
+	 * Sets guideline, stipulation or legislation used for determining conformity
+	 * 
+	 * @param declaration {@link Property}
+	 */
+	public void setGuidelineForConformityDeclaration(Property declaration) {
+		addSubmodelElement(declaration);
+	}
+	
+	/**
+	 * Sets guideline, stipulation or legislation used for determining conformity
+	 * 
+	 * @param declaration {@link String}
+	 */
+	public void setGuidelineForConformityDeclaration(String declaration) {
+		Property declarationProp = new Property(GUIDELINEFORCONFORMITYDECLARATIONID, ValueType.String);
+		declarationProp.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "0173-1#02-AAO856#002", IdentifierType.IRDI)));
+		declarationProp.setValue(declaration);
+		setGuidelineForConformityDeclaration(declarationProp);
+	}
+	
+	/**
+	 * Gets guideline, stipulation or legislation used for determining conformity
+	 * 
+	 * @return
+	 */
+	@SuppressWarnings("unchecked")
+	public IProperty getGuidelineForConformityDeclaration() {
+		return Property.createAsFacade((Map<String, Object>) getSubmodelElement(GUIDELINEFORCONFORMITYDECLARATIONID));
+	}
+	
+	/**
+	 * Gets arbitrary, representing information required by further standards
+	 * @return
+	 */
+	public List<IProperty> getArbitrary() {
+		List<IProperty> ret = new ArrayList<IProperty>();
+		Map<String, ISubmodelElement> elemMap = getSubmodelElements();
+		if (elemMap != null && elemMap.size() > 0) {
+			for (Map.Entry<String, ISubmodelElement> singleElement: elemMap.entrySet()) {
+				if (!singleElement.getKey().equals(GUIDELINEFORCONFORMITYDECLARATIONID)) {
+					ret.add((IProperty) singleElement.getValue());
+				}
+			}
+		}
+		return ret;
+	}
+
+	/**
+	 * Sets arbitrary, representing information required by further standards
+	 * @param arbitraries
+	 */
+	public void setArbitrary(List<Property> arbitraries) {
+		if (arbitraries != null & arbitraries.size() > 0) {
+			for (Property prop : arbitraries) {
+				addSubmodelElement(prop);
+			}
+		}
+	}
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/markings/Marking.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/markings/Marking.java
new file mode 100644
index 0000000..7afd9e8
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/markings/Marking.java
@@ -0,0 +1,218 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.types.digitalnameplate.submodelelementcollections.markings;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyType;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IFile;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
+import org.eclipse.basyx.submodel.metamodel.facade.SubmodelElementMapCollectionConverter;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.File;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.submodel.types.helper.SubmodelElementRetrievalHelper;
+
+/**
+ * Marking as defined in the AAS Digital Nameplate Template document <br/>
+ * It is a submodel element collection which
+ * contains information about the marking labelled on the device
+ * 
+ * @author haque
+ *
+ */
+public class Marking extends SubmodelElementCollection {
+	public static final String MARKINGNAMEID = "MarkingName";
+	public static final String MARKINGFILEID = "MarkingFile";
+	public static final String MARKINGADDITIONALTEXTPREFIX = "MarkingAdditionalText";
+	public static final Reference SEMANTICID = new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "https://admin-shell.io/zvei/nameplate/0/1/Nameplate/Markings/Marking", KeyType.IRI));
+	
+	private Marking() {
+	}
+	
+	/**
+	 * Constructor with mandatory attributes
+	 * 
+	 * @param idShort
+	 * @param markingName
+	 * @param markingFile
+	 */
+	public Marking(String idShort, Property markingName, File markingFile) {
+		super(idShort);
+		setSemanticId(SEMANTICID);
+		setMarkingAdditionalText(new ArrayList<Property>());
+		setMarkingName(markingName);
+		setMarkingFile(markingFile);
+	}
+	
+	/**
+	 * Constructor with mandatory attributes
+	 * 
+	 * @param idShort
+	 * @param markingName
+	 * @param markingFile
+	 */
+	public Marking(String idShort, String markingName, File markingFile) {
+		super(idShort);
+		setSemanticId(SEMANTICID);
+		setMarkingAdditionalText(new ArrayList<Property>());
+		setMarkingName(markingName);
+		setMarkingFile(markingFile);
+	}
+	
+	/**
+	 * Creates a Marking SMC object from a map
+	 * 
+	 * @param obj a Marking SMC object as raw map
+	 * @return a Marking SMC object, that behaves like a facade for the given map
+	 */
+	public static Marking createAsFacade(Map<String, Object> obj) {
+		if (obj == null) {
+			return null;
+		}
+		
+		if (!isValid(obj)) {
+			throw new MetamodelConstructionException(Marking.class, obj);
+		}
+		
+		Marking marking = new Marking();
+		marking.setMap(SubmodelElementMapCollectionConverter.mapToSmECollection(obj));
+		return marking;
+	}
+	
+	/**
+	 * Creates a Marking SMC object from a map without validation
+	 * 
+	 * @param obj a Marking SMC object as raw map
+	 * @return a Marking SMC object, that behaves like a facade for the given map
+	 */
+	private static Marking createAsFacadeNonStrict(Map<String, Object> obj) {
+		if (obj == null) {
+			return null;
+		}
+		
+		Marking marking = new Marking();
+		marking.setMap(SubmodelElementMapCollectionConverter.mapToSmECollection(obj));
+		return marking;
+	}
+	
+	/**
+	 * Check whether all mandatory elements for Marking SMC
+	 * exist in the map
+	 * 
+	 * @param obj
+	 * 
+	 * @return true/false
+	 */
+	@SuppressWarnings("unchecked")
+	public static boolean isValid(Map<String, Object> obj) {
+		Marking marking = createAsFacadeNonStrict(obj);
+		return SubmodelElementCollection.isValid(obj)
+				&& Property.isValid((Map<String, Object>) marking.getMarkingName())
+				&& File.isValid((Map<String, Object>) marking.getMarkingFile());
+	}
+	
+	/**
+	 * Sets common name of the marking
+	 * 
+	 * Note: CE marking is declared as mandatory according to EU
+     * Machine Directive 2006/42/EC.
+	 * @param markingName
+	 */
+	public void setMarkingName(Property markingName) {
+		addSubmodelElement(markingName);
+	}
+	
+	/**
+	 * Sets common name of the marking
+	 * 
+	 * Note: CE marking is declared as mandatory according to EU
+     * Machine Directive 2006/42/EC.
+	 * @param markingName
+	 */
+	public void setMarkingName(String markingName) {
+		Property markingNameProp = new Property(MARKINGNAMEID, ValueType.String);
+		markingNameProp.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "https://admin-shell.io/zvei/nameplate/1/0/Nameplate/Markings/Marking/MarkingName", IdentifierType.IRDI)));
+		markingNameProp.setValue(markingName);
+		setMarkingName(markingNameProp);
+	}
+	
+	/**
+	 * Gets common name of the marking
+	 * 
+	 * Note: CE marking is declared as mandatory according to EU
+     * Machine Directive 2006/42/EC.
+	 * @return
+	 */
+	@SuppressWarnings("unchecked")
+	public IProperty getMarkingName() {
+		return Property.createAsFacade((Map<String, Object>) getSubmodelElement(MARKINGNAMEID));
+	}
+	
+	/**
+	 * Sets picture of the marking
+     * 
+     * Note: CE marking is declared as mandatory according to EU
+     * Machine Directive 2006/42/EC.
+	 * @param markingFile
+	 */
+	public void setMarkingFile(File markingFile) {
+		addSubmodelElement(markingFile);
+	}
+	
+	/**
+	 * Gets picture of the marking
+     * 
+     * Note: CE marking is declared as mandatory according to EU
+     * Machine Directive 2006/42/EC.
+	 * @return
+	 */
+	@SuppressWarnings("unchecked")
+	public IFile getMarkingFile() {
+		return File.createAsFacade((Map<String, Object>) getSubmodelElement(MARKINGFILEID));
+	}
+	
+	/**
+	 * Sets where applicable, additional information on the marking in
+     * plain text
+	 * @param markingAdditionalText
+	 */
+	public void setMarkingAdditionalText(List<Property> markingAdditionalText) {
+		if (markingAdditionalText != null && markingAdditionalText.size() > 0) {
+			for (Property markingAdditionalSingle : markingAdditionalText) {
+				addSubmodelElement(markingAdditionalSingle);
+			}
+		}
+	}
+	
+	/**
+	 * Gets where applicable, additional information on the marking in
+     * plain text
+	 * @return
+	 */
+	public List<IProperty> getMarkingAdditionalText() {
+		List<IProperty> ret = new ArrayList<IProperty>();
+		List<ISubmodelElement> elements = SubmodelElementRetrievalHelper.getSubmodelElementsByIdPrefix(MARKINGADDITIONALTEXTPREFIX, getSubmodelElements());
+		
+		for (ISubmodelElement element: elements) {
+			ret.add((IProperty) element);
+		}
+		return ret;
+	}
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/markings/Markings.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/markings/Markings.java
new file mode 100644
index 0000000..4123443
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/markings/Markings.java
@@ -0,0 +1,157 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.types.digitalnameplate.submodelelementcollections.markings;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyType;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.facade.SubmodelElementMapCollectionConverter;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
+import org.eclipse.basyx.submodel.types.helper.SubmodelElementRetrievalHelper;
+
+/**
+ * Markings as defined in the AAS Digital Nameplate Template document <br/>
+ * It is a submodel element collection which contains a collection of product markings
+ * 
+ * Note: CE marking is declared as mandatory according to EU Machine Directive 2006/42/EC.
+ * 
+ * @author haque
+ *
+ */
+public class Markings extends SubmodelElementCollection {
+	public static final String IDSHORT = "Markings";
+	public static final Reference SEMANTICID = new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "https://admin-shell.io/zvei/nameplate/1/0/Nameplate/Markings", KeyType.IRI));
+	public static final String MARKINGPREFIX = "Marking";
+	
+	private Markings() {
+	}
+	
+	/**
+	 * Constructor with default idShort
+	 * @param markings
+	 */
+	public Markings(List<Marking> markings) {
+		this(IDSHORT, markings);
+	}
+	
+	/**
+	 * Constructor with mandatory attributes
+	 * 
+	 * @param idShort
+	 * @param markings
+	 */
+	public Markings(String idShort, List<Marking> markings) {
+		super(idShort);
+		setSemanticId(SEMANTICID);
+		setMarking(markings);
+	}
+	
+	/**
+	 * Creates a Markings SMC object from a map
+	 * 
+	 * @param obj a Markings SMC object as raw map
+	 * @return a Markings SMC object, that behaves like a facade for the given map
+	 */
+	public static Markings createAsFacade(Map<String, Object> obj) {
+		if (obj == null) {
+			return null;
+		}
+		
+		if (!isValid(obj)) {
+			throw new MetamodelConstructionException(Markings.class, obj);
+		}
+		
+		Markings markings = new Markings();
+		markings.setMap((Map<String, Object>)SubmodelElementMapCollectionConverter.mapToSmECollection(obj));
+		return markings;
+	}
+	
+	/**
+	 * Creates a Markings SMC object from a map without validation
+	 * 
+	 * @param obj a Markings SMC object as raw map
+	 * @return a Markings SMC object, that behaves like a facade for the given map
+	 */
+	private static Markings createAsFacadeNonStrict(Map<String, Object> obj) {
+		if (obj == null) {
+			return null;
+		}
+		
+		Markings markings = new Markings();
+		markings.setMap((Map<String, Object>)SubmodelElementMapCollectionConverter.mapToSmECollection(obj));
+		return markings;
+	}
+	
+	/**
+	 * Check whether all mandatory elements for Markings SMC
+	 * exist in the map
+	 * 
+	 * @param obj
+	 * 
+	 * @return true/false
+	 */
+	public static boolean isValid(Map<String, Object> obj) {
+		Markings markings = createAsFacadeNonStrict(obj);
+		
+		if (SubmodelElementCollection.isValid(obj)
+				&& markings.getMarking() != null
+				&& markings.getMarking().size() > 0) {
+			for (Marking marking : markings.getMarking()) {
+				if (!Marking.isValid((Map<String, Object>) marking)) {
+					return false;
+				}	
+			}
+			return true;
+		}
+		else {
+			return false;	
+		}
+	}
+	
+	/**
+	 * Sets information about the marking labelled on the device
+
+     * Note: CE marking is declared as mandatory according to EU Machine
+     * Directive 2006/42/EC.
+	 * @param markingName
+	 */
+	public void setMarking(List<Marking> markings) {
+		if (markings != null && markings.size() > 0) {
+			for (Marking prop : markings) {
+				addSubmodelElement(prop);
+			}
+		}
+	}
+	
+	/**
+	 * Gets information about the marking labelled on the device
+
+     * Note: CE marking is declared as mandatory according to EU Machine
+     * Directive 2006/42/EC.
+	 * @return
+	 */
+	@SuppressWarnings("unchecked")
+	public List<Marking> getMarking() {
+		List<Marking> ret = new ArrayList<Marking>();
+		List<ISubmodelElement> elements = SubmodelElementRetrievalHelper.getSubmodelElementsByIdPrefix(MARKINGPREFIX, getSubmodelElements());
+		
+		for (ISubmodelElement element: elements) {
+			ret.add(Marking.createAsFacade((Map<String, Object>) element));
+		}
+		return ret;
+	}
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/helper/SubmodelElementRetrievalHelper.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/helper/SubmodelElementRetrievalHelper.java
new file mode 100644
index 0000000..a5fccbd
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/helper/SubmodelElementRetrievalHelper.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.submodel.types.helper;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+
+public class SubmodelElementRetrievalHelper {
+	
+	public static List<ISubmodelElement> getSubmodelElementsByIdPrefix(String prefix, Map<String, ISubmodelElement> elemMap) {
+		if (elemMap != null && elemMap.size() > 0) {
+			return elemMap.values().stream().filter(s -> s.getIdShort().startsWith(prefix)).collect(Collectors.toList());
+		}
+		return new ArrayList<ISubmodelElement>();
+	}
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/technicaldata/TechnicalDataSubmodel.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/technicaldata/TechnicalDataSubmodel.java
new file mode 100644
index 0000000..8f61c9d
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/technicaldata/TechnicalDataSubmodel.java
@@ -0,0 +1,223 @@
+/*******************************************************************************
+* Copyright (C) 2021 the Eclipse BaSyx Authors
+* 
+* This program and the accompanying materials are made
+* available under the terms of the Eclipse Public License 2.0
+* which is available at https://www.eclipse.org/legal/epl-2.0/
+
+* 
+* SPDX-License-Identifier: EPL-2.0
+******************************************************************************/
+
+package org.eclipse.basyx.submodel.types.technicaldata;
+
+import java.util.Collections;
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyType;
+import org.eclipse.basyx.submodel.metamodel.facade.SubmodelElementMapCollectionConverter;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
+import org.eclipse.basyx.submodel.types.technicaldata.submodelelementcollections.furtherinformation.FurtherInformation;
+import org.eclipse.basyx.submodel.types.technicaldata.submodelelementcollections.generalinformation.GeneralInformation;
+import org.eclipse.basyx.submodel.types.technicaldata.submodelelementcollections.productclassifications.ProductClassifications;
+import org.eclipse.basyx.submodel.types.technicaldata.submodelelementcollections.technicalproperties.TechnicalProperties;
+
+/**
+ * TechnicalDataSubmodel as described in the Submodel Template AAS Technical Data Document
+ * 
+ * this contains Submodel containing technical data of the asset and associated product classifications.
+ * 
+ * @author haque
+ *
+ */
+public class TechnicalDataSubmodel extends Submodel {
+	public static final String GENERALINFORMATIONID = "GeneralInformation";
+	public static final String PRODUCTCLASSIFICATIONSID = "ProductClassifications";
+	public static final String TECHNICALPROPERTIESID = "TechnicalProperties";
+	public static final String FURTHERINFORMATIONID = "FurtherInformation";
+	public static final Reference SEMANTICID = new Reference(Collections.singletonList(new Key(KeyElements.CONCEPTDESCRIPTION, false, "http://admin-shell.io/ZVEI/TechnicalData/Submodel/1/1", KeyType.IRI)));
+	public static final String SUBMODELID = "TechnicalData";
+	
+	private TechnicalDataSubmodel() {}
+	
+	/**
+	 * Constructor with default idShort
+	 * @param identifier
+	 * @param generalInformation
+	 * @param productClassifications
+	 * @param properties
+	 * @param furtherInformation
+	 */
+	public TechnicalDataSubmodel(
+			Identifier identifier,
+			GeneralInformation generalInformation, 
+			ProductClassifications productClassifications, 
+			TechnicalProperties properties, 
+			FurtherInformation furtherInformation
+			) {
+		this(SUBMODELID, identifier, generalInformation, productClassifications, properties, furtherInformation);
+	}
+	
+	/**
+	 * Constructor with mandatory attributes
+	 * @param idShort
+	 * @param identifier
+	 * @param manufacturerName
+	 * @param manufacturerProductDesignation
+	 * @param address
+	 * @param manufacturerProductFamily
+	 * @param yearsOfConstruction
+	 */
+	public TechnicalDataSubmodel(
+			String idShort,
+			Identifier identifier,
+			GeneralInformation generalInformation, 
+			ProductClassifications productClassifications, 
+			TechnicalProperties properties, 
+			FurtherInformation furtherInformation
+			) {
+		super(idShort, identifier);
+		setSemanticId(SEMANTICID);
+		setGeneralInformation(generalInformation);
+		setProductClassifications(productClassifications);
+		setTechnicalProperties(properties);
+		setFurtherInformation(furtherInformation);
+	}
+	
+	/**
+	 * Creates a TechnicalDataSubmodel object from a map
+	 * 
+	 * @param obj a TechnicalDataSubmodel SMC object as raw map
+	 * @return a TechnicalDataSubmodel SMC object, that behaves like a facade for the given map
+	 */
+	public static TechnicalDataSubmodel createAsFacade(Map<String, Object> obj) {
+		if (obj == null) {
+			return null;
+		}
+		
+		if (!isValid(obj)) {
+			throw new MetamodelConstructionException(TechnicalDataSubmodel.class, obj);
+		}
+		
+		TechnicalDataSubmodel ret = new TechnicalDataSubmodel();
+		ret.setMap((Map<String, Object>)SubmodelElementMapCollectionConverter.mapToSM(obj));
+		return ret;
+	}
+	
+	/**
+	 * Creates a TechnicalDataSubmodel object from a map without validation
+	 * 
+	 * @param obj a TechnicalDataSubmodel SMC object as raw map
+	 * @return a TechnicalDataSubmodel SMC object, that behaves like a facade for the given map
+	 */
+	private static TechnicalDataSubmodel createAsFacadeNonStrict(Map<String, Object> obj) {
+		if (obj == null) {
+			return null;
+		}
+		
+		TechnicalDataSubmodel ret = new TechnicalDataSubmodel();
+		ret.setMap((Map<String, Object>)SubmodelElementMapCollectionConverter.mapToSM(obj));
+		return ret;
+	}
+	
+	/**
+	 * Check whether all mandatory elements for TechnicalDataSubmodel
+	 * exist in the map
+	 * 
+	 * @param obj
+	 * 
+	 * @return true/false
+	 */
+	public static boolean isValid(Map<String, Object> obj) {
+		TechnicalDataSubmodel submodel = createAsFacadeNonStrict(obj);
+		
+		return Submodel.isValid(obj)
+				&& GeneralInformation.isValid((Map<String, Object>) submodel.getGeneralInformation())
+				&& TechnicalProperties.isValid((Map<String, Object>) submodel.getTechnicalProperties());
+	}
+	
+	/**
+	 * Sets general information, for example ordering and manufacturer information.
+	 * 
+	 * @param information
+	 */
+	public void setGeneralInformation(GeneralInformation information) {
+		addSubmodelElement(information);
+	}
+	
+	/**
+	 * 
+	 * Gets general information, for example ordering and manufacturer information.
+	 * 
+	 * @return
+	 */
+	@SuppressWarnings("unchecked")
+	public GeneralInformation getGeneralInformation() {
+		return GeneralInformation.createAsFacade((Map<String, Object>) getSubmodelElement(GENERALINFORMATIONID));
+	}
+	
+	/**
+	 * Sets product classifications by association of product classes with common classification systems.
+	 * 
+	 * @param classifications
+	 */
+	public void setProductClassifications(ProductClassifications classifications) {
+		addSubmodelElement(classifications);
+	}
+	
+	/**
+	 * 
+	 * Gets product classifications by association of product classes with common classification systems.
+	 * 
+	 * @return
+	 */
+	@SuppressWarnings("unchecked")
+	public ProductClassifications getProductClassifications() {
+		return ProductClassifications.createAsFacade((Map<String, Object>) getSubmodelElement(PRODUCTCLASSIFICATIONSID));
+	}
+	
+	/**
+	 * Sets technical and product properties. Individual characteristics that describe the product and its technical properties.
+	 * 
+	 * @param properties
+	 */
+	public void setTechnicalProperties(TechnicalProperties properties) {
+		addSubmodelElement(properties);
+	}
+	
+	/**
+	 * 
+	 * Gets technical and product properties. Individual characteristics that describe the product and its technical properties.
+	 * 
+	 * @return
+	 */
+	@SuppressWarnings("unchecked")
+	public TechnicalProperties getTechnicalProperties() {
+		return TechnicalProperties.createAsFacade((Map<String, Object>) getSubmodelElement(TECHNICALPROPERTIESID));
+	}
+	
+	/**
+	 * Sets further information on the product, the validity of the information provided and this data record.
+	 * 
+	 * @param information
+	 */
+	public void setFurtherInformation(FurtherInformation information) {
+		addSubmodelElement(information);
+	}
+	
+	/**
+	 * 
+	 * Gets further information on the product, the validity of the information provided and this data record.
+	 * 
+	 * @return
+	 */
+	@SuppressWarnings("unchecked")
+	public FurtherInformation getFurtherInformation() {
+		return FurtherInformation.createAsFacade((Map<String, Object>) getSubmodelElement(FURTHERINFORMATIONID));
+	}
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/technicaldata/submodelelementcollections/furtherinformation/FurtherInformation.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/technicaldata/submodelelementcollections/furtherinformation/FurtherInformation.java
new file mode 100644
index 0000000..7b355ca
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/technicaldata/submodelelementcollections/furtherinformation/FurtherInformation.java
@@ -0,0 +1,225 @@
+/*******************************************************************************
+* Copyright (C) 2021 the Eclipse BaSyx Authors
+* 
+* This program and the accompanying materials are made
+* available under the terms of the Eclipse Public License 2.0
+* which is available at https://www.eclipse.org/legal/epl-2.0/
+
+* 
+* SPDX-License-Identifier: EPL-2.0
+******************************************************************************/
+
+package org.eclipse.basyx.submodel.types.technicaldata.submodelelementcollections.furtherinformation;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.datatype.XMLGregorianCalendar;
+
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyType;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IMultiLanguageProperty;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
+import org.eclipse.basyx.submodel.metamodel.facade.SubmodelElementMapCollectionConverter;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.MultiLanguageProperty;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.submodel.types.helper.SubmodelElementRetrievalHelper;
+
+/**
+ * FurtherInformation as described in the Submodel Template AAS Technical Data Document
+ * It contains Further information on the product, the validity of the information provided and this data record.
+ * 
+ * @author haque
+ *
+ */
+public class FurtherInformation extends SubmodelElementCollection {
+	public static final String IDSHORT = "FurtherInformation";
+	public static final Reference SEMANTICID = new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "https://admin-shell.io/ZVEI/TechnicalData/FurtherInformation/1/1", KeyType.IRI));
+	public static final String TEXTSTATEMENTPREFIX = "TextStatement";
+	public static final String VALIDDATEID = "ValidDate";
+	
+	private FurtherInformation() {
+	}
+	
+	/**
+	 * Constructor with default idShort
+	 * @param validDate
+	 */
+	public FurtherInformation(Property validDate) {
+		this(IDSHORT, validDate);
+	}
+	
+	/**
+	 * Constructor with default idShort
+	 * @param validDate
+	 */
+	public FurtherInformation(XMLGregorianCalendar validDate) {
+		this(IDSHORT, validDate);
+	}
+	
+	/**
+	 * Constructor with mandatory attributes
+	 * 
+	 * @param idShort
+	 * @param validDate
+	 */
+	public FurtherInformation(String idShort, Property validDate) {
+		super(idShort);
+		setSemanticId(SEMANTICID);
+		setValidDate(validDate);
+		setTextStatements(new ArrayList<MultiLanguageProperty>());
+	}
+	
+	/**
+	 * Constructor with mandatory attributes
+	 * 
+	 * @param idShort
+	 * @param validDate
+	 */
+	public FurtherInformation(String idShort, XMLGregorianCalendar validDate) {
+		super(idShort);
+		setSemanticId(SEMANTICID);
+		setValidDate(validDate);
+		setTextStatements(new ArrayList<MultiLanguageProperty>());
+	}
+	
+	/**
+	 * Creates a FurtherInformation SMC object from a map
+	 * 
+	 * @param obj a FurtherInformation SMC object as raw map
+	 * @return a FurtherInformation SMC object, that behaves like a facade for the given map
+	 */
+	public static FurtherInformation createAsFacade(Map<String, Object> obj) {
+		if (obj == null) {
+			return null;
+		}
+		
+		if (!isValid(obj)) {
+			throw new MetamodelConstructionException(FurtherInformation.class, obj);
+		}
+		
+		FurtherInformation furtherInformation = new FurtherInformation();
+		furtherInformation.setMap(SubmodelElementMapCollectionConverter.mapToSmECollection(obj));
+		return furtherInformation;
+	}
+	
+	/**
+	 * Creates a FurtherInformation SMC object from a map without validation
+	 * 
+	 * @param obj a FurtherInformation SMC object as raw map
+	 * @return a FurtherInformation SMC object, that behaves like a facade for the given map
+	 */
+	private static FurtherInformation createAsFacadeNonStrict(Map<String, Object> obj) {
+		if (obj == null) {
+			return null;
+		}
+		
+		FurtherInformation furtherInformation = new FurtherInformation();
+		furtherInformation.setMap(SubmodelElementMapCollectionConverter.mapToSmECollection(obj));
+		return furtherInformation;
+	}
+	
+	/**
+	 * Check whether all mandatory elements for FurtherInformation SMC
+	 * exist in the map
+	 * 
+	 * @param obj
+	 * 
+	 * @return true/false
+	 */
+	@SuppressWarnings("unchecked")
+	public static boolean isValid(Map<String, Object> obj) {
+		FurtherInformation furtherInformation = createAsFacadeNonStrict(obj);
+		
+		return SubmodelElementCollection.isValid(obj)
+				&& Property.isValid((Map<String, Object>) furtherInformation.getValidDate());
+	}
+	
+	/**
+	 * Sets statement by the manufacturer in text form, 
+	 * e.g. scope of validity of the statements, scopes of application, 
+	 * conditions of operation.
+	 * 
+	 * Note: Whenever possible, a multi-language definition is preferred.
+	 * 
+	 * @param statements
+	 */
+	public void setTextStatements(List<MultiLanguageProperty> statements) {
+		if (statements != null && statements.size() > 0) {
+			for (MultiLanguageProperty statement: statements) {
+				addSubmodelElement(statement);
+			}
+		}
+	}
+	
+	/**
+	 * Gets statement by the manufacturer in text form, 
+	 * e.g. scope of validity of the statements, scopes of application, 
+	 * conditions of operation.
+	 * 
+	 * Note: Whenever possible, a multi-language definition is preferred.
+	 * 
+	 * @return
+	 */
+	@SuppressWarnings("unchecked")
+	public List<IMultiLanguageProperty> getStatements() {
+		List<IMultiLanguageProperty> ret = new ArrayList<IMultiLanguageProperty>();
+		List<ISubmodelElement> elements = SubmodelElementRetrievalHelper.getSubmodelElementsByIdPrefix(TEXTSTATEMENTPREFIX, getSubmodelElements());
+		
+		for (ISubmodelElement element: elements) {
+			ret.add(MultiLanguageProperty.createAsFacade((Map<String, Object>) element));
+		}
+		return ret;
+	}
+	
+	/**
+	 * Sets a date on which the data specified in the Submodel was valid from for the associated asset.
+	 * 
+	 * Note: Often this date will be the date of the last update of the 
+	 * corresponding data, that are the source for the technical properties 
+	 * section in the master data system.
+	 * 
+	 * @param validDate
+	 */
+	public void setValidDate(Property validDate) {
+		addSubmodelElement(validDate);
+	}
+	
+	/**
+	 * Sets a date on which the data specified in the Submodel was valid from for the associated asset.
+	 * 
+	 * Note: Often this date will be the date of the last update of the 
+	 * corresponding data, that are the source for the technical properties 
+	 * section in the master data system.
+	 * 
+	 * @param validDate
+	 */
+	public void setValidDate(XMLGregorianCalendar validDate) {
+		Property validDateProp = new Property(VALIDDATEID, ValueType.DateTime);
+		validDateProp.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "https://admin-shell.io/ZVEI/TechnicalData/ValidDate/1/1", IdentifierType.IRI)));
+		validDateProp.setValue(validDate);
+		setValidDate(validDateProp);
+	}
+	
+	/**
+	 * Gets a date on which the data specified in the Submodel was valid from for the associated asset.
+	 * 
+	 * Note: Often this date will be the date of the last update of the 
+	 * corresponding data, that are the source for the technical properties 
+	 * section in the master data system.
+	 * 
+	 * @return
+	 */
+	@SuppressWarnings("unchecked")
+	public IProperty getValidDate() {
+		return Property.createAsFacade((Map<String, Object>) getSubmodelElement(VALIDDATEID));
+	}
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/technicaldata/submodelelementcollections/generalinformation/GeneralInformation.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/technicaldata/submodelelementcollections/generalinformation/GeneralInformation.java
new file mode 100644
index 0000000..b7533ad
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/technicaldata/submodelelementcollections/generalinformation/GeneralInformation.java
@@ -0,0 +1,352 @@
+/*******************************************************************************
+* Copyright (C) 2021 the Eclipse BaSyx Authors
+* 
+* This program and the accompanying materials are made
+* available under the terms of the Eclipse Public License 2.0
+* which is available at https://www.eclipse.org/legal/epl-2.0/
+
+* 
+* SPDX-License-Identifier: EPL-2.0
+******************************************************************************/
+
+package org.eclipse.basyx.submodel.types.technicaldata.submodelelementcollections.generalinformation;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyType;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IFile;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IMultiLanguageProperty;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
+import org.eclipse.basyx.submodel.metamodel.facade.SubmodelElementMapCollectionConverter;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangString;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangStrings;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.File;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.MultiLanguageProperty;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.submodel.types.helper.SubmodelElementRetrievalHelper;
+
+/**
+ * GeneralInformation as described in the Submodel Template AAS Technical Data Document
+ * 
+ * It is a submodel element collection which contains General information, for example ordering and manufacturer information.
+ * 
+ * @author haque
+ *
+ */
+public class GeneralInformation extends SubmodelElementCollection{
+	public static final String IDSHORT = "GeneralInformation";
+	public static final String MANUFACTURERNAMEID = "ManufacturerName";
+	public static final String MANUFACTURERLOGOID = "ManufacturerLogo";
+	public static final String MANUFACTURERPRODUCTDESIGNATIONID = "ManufacturerProductDesignation";
+	public static final String MANUFACTURERPARTNUMBERID = "ManufacturerPartNumber";
+	public static final String MANUFACTURERORDERCODEID = "ManufacturerOrderCode";
+	public static final String PRODUCTIMAGEPREFIX = "ProductImage";
+	public static final Reference SEMANTICID = new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "https://admin-shell.io/ZVEI/TechnicalData/GeneralInformation/1/1", KeyType.IRI));
+	
+	private GeneralInformation() {
+	}
+
+	/**
+	 * Constructor with default idShort
+	 * 
+	 * @param manufacturerName
+	 * @param manufacturerProductDesignation
+	 * @param manufacturerPartNumber
+	 * @param manufacturerOrderCode
+	 */
+	public GeneralInformation(Property manufacturerName, MultiLanguageProperty manufacturerProductDesignation, Property manufacturerPartNumber, Property manufacturerOrderCode) {
+		this(IDSHORT, manufacturerName, manufacturerProductDesignation, manufacturerPartNumber, manufacturerOrderCode);
+	}
+	
+	/**
+	 * Constructor with default idShort
+	 * 
+	 * @param manufacturerName
+	 * @param manufacturerProductDesignation
+	 * @param manufacturerPartNumber
+	 * @param manufacturerOrderCode
+	 */
+	public GeneralInformation(String manufacturerName, LangString manufacturerProductDesignation, String manufacturerPartNumber, String manufacturerOrderCode) {
+		this(IDSHORT, manufacturerName, manufacturerProductDesignation, manufacturerPartNumber, manufacturerOrderCode);
+	}
+	
+	/**
+	 * Constructor with mandatory attributes
+	 * 
+	 * @param idShort
+	 * @param manufacturerName
+	 * @param manufacturerProductDesignation
+	 * @param manufacturerPartNumber
+	 * @param manufacturerOrderCode
+	 */
+	public GeneralInformation(String idShort, Property manufacturerName, MultiLanguageProperty manufacturerProductDesignation, Property manufacturerPartNumber, Property manufacturerOrderCode) {
+		super(idShort);
+		setSemanticId(SEMANTICID);
+		setManufacturerName(manufacturerName);
+		setManufacturerProductDesignation(manufacturerProductDesignation);
+		setManufacturerPartNumber(manufacturerPartNumber);
+		setManufacturerOrderCode(manufacturerOrderCode);
+	}
+	
+	/**
+	 * Constructor with mandatory attributes
+	 * 
+	 * @param idShort
+	 * @param manufacturerName
+	 * @param manufacturerProductDesignation
+	 * @param manufacturerPartNumber
+	 * @param manufacturerOrderCode
+	 */
+	public GeneralInformation(String idShort, String manufacturerName, LangString manufacturerProductDesignation, String manufacturerPartNumber, String manufacturerOrderCode) {
+		super(idShort);
+		setSemanticId(SEMANTICID);
+		setManufacturerName(manufacturerName);
+		setManufacturerProductDesignation(manufacturerProductDesignation);
+		setManufacturerPartNumber(manufacturerPartNumber);
+		setManufacturerOrderCode(manufacturerOrderCode);
+	}
+	
+	/**
+	 * Creates a GeneralInformation SMC object from a map
+	 * 
+	 * @param obj a GeneralInformation SMC object as raw map
+	 * @return a GeneralInformation SMC object, that behaves like a facade for the given map
+	 */
+	public static GeneralInformation createAsFacade(Map<String, Object> obj) {
+		if (obj == null) {
+			return null;
+		}
+		
+		if (!isValid(obj)) {
+			throw new MetamodelConstructionException(GeneralInformation.class, obj);
+		}
+		
+		GeneralInformation generalInformation = new GeneralInformation();
+		generalInformation.setMap(SubmodelElementMapCollectionConverter.mapToSmECollection(obj));
+		return generalInformation;
+	}
+	
+	/**
+	 * Creates a GeneralInformation SMC object from a map without validation
+	 * 
+	 * @param obj a GeneralInformation SMC object as raw map
+	 * @return a GeneralInformation SMC object, that behaves like a facade for the given map
+	 */
+	private static GeneralInformation createAsFacadeNonStrict(Map<String, Object> obj) {
+		if (obj == null) {
+			return null;
+		}
+		
+		GeneralInformation generalInformation = new GeneralInformation();
+		generalInformation.setMap(SubmodelElementMapCollectionConverter.mapToSmECollection(obj));
+		return generalInformation;
+	}
+	
+	/**
+	 * Check whether all mandatory elements for GeneralInformation SMC
+	 * exist in the map
+	 * 
+	 * @param obj
+	 * 
+	 * @return true/false
+	 */
+	@SuppressWarnings("unchecked")
+	public static boolean isValid(Map<String, Object> obj) {
+		GeneralInformation generalInformation = createAsFacadeNonStrict(obj);
+		return SubmodelElementCollection.isValid(obj)
+				&& Property.isValid((Map<String, Object>) generalInformation.getManufacturerName())
+				&& MultiLanguageProperty.isValid((Map<String, Object>) generalInformation.getManufacturerProductDesignation())
+				&& Property.isValid((Map<String, Object>) generalInformation.getManufacturerPartNumber())
+				&& Property.isValid((Map<String, Object>) generalInformation.getManufacturerOrderCode());
+	}
+	
+	/**
+	 * Sets legally valid designation of the natural or judicial body which is directly responsible for the design, production, packaging and labeling of a product in respect to its being brought into the market.
+	 * 
+	 * @param name
+	 */
+	public void setManufacturerName(Property name) {
+		addSubmodelElement(name);
+	}
+	
+	/**
+	 * Sets legally valid designation of the natural or judicial body which is directly responsible for the design, production, packaging and labeling of a product in respect to its being brought into the market.
+	 * 
+	 * @param name
+	 */
+	public void setManufacturerName(String name) {
+		Property nameProp = new Property(MANUFACTURERNAMEID, ValueType.String);
+		nameProp.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "https://admin-shell.io/ZVEI/TechnicalData/ManufacturerName/1/1", IdentifierType.IRI)));
+		nameProp.setValue(name);
+		setManufacturerName(nameProp);
+	}
+	
+	/**
+	 * Gets legally valid designation of the natural or judicial body which is directly responsible for the design, production, packaging and labeling of a product in respect to its being brought into the market.
+	 * 
+	 * @return
+	 */
+	@SuppressWarnings("unchecked")
+	public IProperty getManufacturerName() {
+		return Property.createAsFacade((Map<String, Object>) getSubmodelElement(MANUFACTURERNAMEID));
+	}
+	
+	/**
+	 * Sets imagefile for logo of manufacturer provided in common format (.png, .jpg).
+	 * 
+	 * @param logo
+	 */
+	public void setManufacturerLogo(File logo) {
+		addSubmodelElement(logo);
+	}
+	
+	/**
+	 * Gets imagefile for logo of manufacturer provided in common format (.png, .jpg).
+	 * 
+	 * @return
+	 */
+	@SuppressWarnings("unchecked")
+	public IFile getManufacturerLogo() {
+		return File.createAsFacade((Map<String, Object>) getSubmodelElement(MANUFACTURERLOGOID));
+	}
+	
+	/**
+	 * Sets product designation as given by the mnaufacturer. Short description of the product, product group or function (short text) in common language.
+	 * 
+	 * Note: Whenever possible, a multi-language definition is preferred.
+	 * 
+	 * @param designation {@link MultiLanguageProperty}
+	 */
+	public void setManufacturerProductDesignation(MultiLanguageProperty designation) {
+		addSubmodelElement(designation);
+	}
+	
+	/**
+	 * Sets product designation as given by the mnaufacturer. Short description of the product, product group or function (short text) in common language.
+	 * 
+	 * Note: Whenever possible, a multi-language definition is preferred.
+	 * 
+	 * @param designation {@link LangString}
+	 */
+	public void setManufacturerProductDesignation(LangString designation) {
+		MultiLanguageProperty designationProp = new MultiLanguageProperty(MANUFACTURERPRODUCTDESIGNATIONID);
+		designationProp.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "https://admin-shell.io/ZVEI/TechnicalData/ManufacturerProductDesignation/1/1", IdentifierType.IRI)));
+		designationProp.setValue(new LangStrings(designation));
+		setManufacturerProductDesignation(designationProp);
+	}
+	
+	/**
+	 * Gets product designation as given by the mnaufacturer. Short description of the product, product group or function (short text) in common language.
+	 * 
+	 * Note: Whenever possible, a multi-language definition is preferred.
+	 * @return
+	 */
+	@SuppressWarnings("unchecked")
+	public IMultiLanguageProperty getManufacturerProductDesignation() {
+		return MultiLanguageProperty.createAsFacade((Map<String, Object>) getSubmodelElement(MANUFACTURERPRODUCTDESIGNATIONID));
+	}
+	
+	/**
+	 * Sets unique product identifier of the manufacturer for the product type respective the type designation of the industrial equipemnt.
+	 * 
+	 * Note: The Manufacturer part number is represented as a string, although often a numerical id.
+	 * @param partNumber
+	 */
+	public void setManufacturerPartNumber(Property partNumber) {
+		addSubmodelElement(partNumber);
+	}
+	
+	/**
+	 * Sets unique product identifier of the manufacturer for the product type respective the type designation of the industrial equipemnt.
+	 * 
+	 * Note: The Manufacturer part number is represented as a string, although often a numerical id.
+	 * @param partNumber
+	 */
+	public void setManufacturerPartNumber(String partNumber) {
+		Property partNumberProp = new Property(MANUFACTURERPARTNUMBERID, ValueType.String);
+		partNumberProp.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "https://admin-shell.io/ZVEI/TechnicalData/ManufacturerPartNumber/1/1", IdentifierType.IRI)));
+		partNumberProp.setValue(partNumber);
+		setManufacturerPartNumber(partNumberProp);
+	}
+	
+	/**
+	 * Gets unique product identifier of the manufacturer for the product type respective the type designation of the industrial equipemnt.
+	 * 
+	 * Note: The Manufacturer part number is represented as a string, although often a numerical id.
+	 * @return
+	 */
+	@SuppressWarnings("unchecked")
+	public IProperty getManufacturerPartNumber() {
+		return Property.createAsFacade((Map<String, Object>) getSubmodelElement(MANUFACTURERPARTNUMBERID));
+	}
+	
+	/**
+	 * Sets unique product identifier of the manufacturer sufficient to order the exact same product.
+	 * 
+	 * @param orderCode
+	 */
+	public void setManufacturerOrderCode(Property orderCode) {
+		addSubmodelElement(orderCode);
+	}
+	
+	/**
+	 * Sets unique product identifier of the manufacturer sufficient to order the exact same product.
+	 * 
+	 * @param orderCode
+	 */
+	public void setManufacturerOrderCode(String orderCode) {
+		Property orderCodeProp = new Property(MANUFACTURERORDERCODEID, ValueType.String);
+		orderCodeProp.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "https://admin-shell.io/ZVEI/TechnicalData/ManufacturerOrderCode/1/1", IdentifierType.IRI)));
+		orderCodeProp.setValue(orderCode);
+		setManufacturerOrderCode(orderCodeProp);
+	}
+	
+	/**
+	 * Gets unique product identifier of the manufacturer sufficient to order the exact same product.
+	 * 
+	 * @return
+	 */
+	@SuppressWarnings("unchecked")
+	public IProperty getManufacturerOrderCode() {
+		return Property.createAsFacade((Map<String, Object>) getSubmodelElement(MANUFACTURERORDERCODEID));
+	}
+	
+	/**
+	 * Sets image file for associated product provided in common format (.png, .jpg).
+	 * 
+	 * @param image
+	 */
+	public void setProductImages(List<File> images) {
+		if (images != null && images.size() > 0) {
+			for (File image : images) {
+				addSubmodelElement(image);
+			}
+		}
+	}
+	
+	/**
+	 * Gets image file for associated product provided in common format (.png, .jpg).
+	 * 
+	 * @return
+	 */
+	@SuppressWarnings("unchecked")
+	public List<IFile> getProductImages() {
+		List<IFile> ret = new ArrayList<IFile>();
+		List<ISubmodelElement> elements = SubmodelElementRetrievalHelper.getSubmodelElementsByIdPrefix(PRODUCTIMAGEPREFIX, getSubmodelElements());
+		
+		for (ISubmodelElement element: elements) {
+			ret.add(File.createAsFacade((Map<String, Object>) element));
+		}
+		return ret;
+	}
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/technicaldata/submodelelementcollections/productclassifications/ProductClassificationItem.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/technicaldata/submodelelementcollections/productclassifications/ProductClassificationItem.java
new file mode 100644
index 0000000..647e9a0
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/technicaldata/submodelelementcollections/productclassifications/ProductClassificationItem.java
@@ -0,0 +1,228 @@
+/*******************************************************************************
+* Copyright (C) 2021 the Eclipse BaSyx Authors
+* 
+* This program and the accompanying materials are made
+* available under the terms of the Eclipse Public License 2.0
+* which is available at https://www.eclipse.org/legal/epl-2.0/
+
+* 
+* SPDX-License-Identifier: EPL-2.0
+******************************************************************************/
+
+package org.eclipse.basyx.submodel.types.technicaldata.submodelelementcollections.productclassifications;
+
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyType;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
+import org.eclipse.basyx.submodel.metamodel.facade.SubmodelElementMapCollectionConverter;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+
+/**
+ * ProductClassificationItem as described in the Submodel Template AAS Technical Data Document
+ * 
+ * It is a submodel element collection which contains Single product 
+ * classification by association with product class in a particular 
+ * classification system or property dictionary.
+ * 
+ * @author haque
+ *
+ */
+public class ProductClassificationItem extends SubmodelElementCollection {
+	public static final String PRODUCTCLASSIFICATIONSYSTEMID = "ProductClassificationSystem";
+	public static final String CLASSIFICATIONSYSTEMVERSIONID = "ClassificationSystemVersion";
+	public static final String PRODUCTCLASSID = "ProductClassId";
+	public static final Reference SEMANTICID = new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "https://admin-shell.io/ZVEI/TechnicalData/ProductClassificationItem/1/1", KeyType.IRI));
+	
+	private ProductClassificationItem() {
+	}
+	
+	/**
+	 * Constructor with mandatory attributes
+	 * 
+	 * @param idShort
+	 * @param productClassificationSystem
+	 * @param productClassId
+	 */
+	public ProductClassificationItem(String idShort, Property productClassificationSystem, Property productClassId) {
+		super(idShort);
+		setSemanticId(SEMANTICID);
+		setProductClassificationSystem(productClassificationSystem);
+		setProductClassId(productClassId);
+	}
+	
+	/**
+	 * Constructor with mandatory attributes
+	 * 
+	 * @param idShort
+	 * @param productClassificationSystem
+	 * @param productClassId
+	 */
+	public ProductClassificationItem(String idShort, String productClassificationSystem, String productClassId) {
+		super(idShort);
+		setSemanticId(SEMANTICID);
+		setProductClassificationSystem(productClassificationSystem);
+		setProductClassId(productClassId);
+	}
+	
+	/**
+	 * Creates a ProductClassificationItem SMC object from a map
+	 * 
+	 * @param obj a ProductClassificationItem SMC object as raw map
+	 * @return a ProductClassificationItem SMC object, that behaves like a facade for the given map
+	 */
+	public static ProductClassificationItem createAsFacade(Map<String, Object> obj) {
+		if (obj == null) {
+			return null;
+		}
+		
+		if (!isValid(obj)) {
+			throw new MetamodelConstructionException(ProductClassificationItem.class, obj);
+		}
+		
+		ProductClassificationItem productClassificationItem = new ProductClassificationItem();
+		productClassificationItem.setMap(SubmodelElementMapCollectionConverter.mapToSmECollection(obj));
+		return productClassificationItem;
+	}
+	
+	/**
+	 * Creates a ProductClassificationItem SMC object from a map without validation
+	 * 
+	 * @param obj a ProductClassificationItem SMC object as raw map
+	 * @return a ProductClassificationItem SMC object, that behaves like a facade for the given map
+	 */
+	private static ProductClassificationItem createAsFacadeNonStrict(Map<String, Object> obj) {
+		if (obj == null) {
+			return null;
+		}
+		
+		ProductClassificationItem productClassificationItem = new ProductClassificationItem();
+		productClassificationItem.setMap(SubmodelElementMapCollectionConverter.mapToSmECollection(obj));
+		return productClassificationItem;
+	}
+	
+	/**
+	 * Check whether all mandatory elements for ProdictClassificationSystem SMC
+	 * exist in the map
+	 * 
+	 * @param obj
+	 * 
+	 * @return true/false
+	 */
+	@SuppressWarnings("unchecked")
+	public static boolean isValid(Map<String, Object> obj) {
+		ProductClassificationItem productClassificationItem = createAsFacadeNonStrict(obj);
+		return SubmodelElementCollection.isValid(obj)
+				&& Property.isValid((Map<String, Object>) productClassificationItem.getProductClassificationSystem())
+				&& Property.isValid((Map<String, Object>) productClassificationItem.getProductClassId());
+	}
+	
+	/**
+	 * Sets common name of the classification system.
+	 * 
+	 * Note: Examples for common names for classification systems are "ECLASS" or "IEC CDD".
+	 * @param system
+	 */
+	public void setProductClassificationSystem(Property system) {
+		addSubmodelElement(system);
+	}
+	
+	/**
+	 * Sets common name of the classification system.
+	 * 
+	 * Note: Examples for common names for classification systems are "ECLASS" or "IEC CDD".
+	 * @param system
+	 */
+	public void setProductClassificationSystem(String system) {
+		Property productClassificationSystemProp = new Property(PRODUCTCLASSIFICATIONSYSTEMID, ValueType.String);
+		productClassificationSystemProp.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "https://admin-shell.io/ZVEI/TechnicalData/ProductClassificationSystem/1/1", IdentifierType.IRI)));
+		productClassificationSystemProp.setValue(system);
+		setProductClassificationSystem(productClassificationSystemProp);
+	}
+	
+	/**
+	 * Gets common name of the classification system.
+	 * 
+	 * Note: Examples for common names for classification systems are "ECLASS" or "IEC CDD".
+	 * @return
+	 */
+	@SuppressWarnings("unchecked")
+	public IProperty getProductClassificationSystem() {
+		return Property.createAsFacade((Map<String, Object>) getSubmodelElement(PRODUCTCLASSIFICATIONSYSTEMID));
+	}
+	
+	/**
+	 * Sets common version identifier of the used classification system, in order to distinguish different version of the property dictionary.
+	 * 
+	 * Note: Casing is to be ignored.
+	 * @param version
+	 */
+	public void setClassificationSystemVersion(Property version) {
+		addSubmodelElement(version);
+	}
+	
+	/**
+	 * Sets common version identifier of the used classification system, in order to distinguish different version of the property dictionary.
+	 * 
+	 * Note: Casing is to be ignored.
+	 * @param system
+	 */
+	public void setClassificationSystemVersion(String version) {
+		Property versionProp = new Property(CLASSIFICATIONSYSTEMVERSIONID, ValueType.String);
+		versionProp.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "https://admin-shell.io/ZVEI/TechnicalData/ClassificationSystemVersion/1/1", IdentifierType.IRI)));
+		versionProp.setValue(version);
+		setClassificationSystemVersion(versionProp);
+	}
+	
+	/**
+	 * Gets common version identifier of the used classification system, in order to distinguish different version of the property dictionary.
+	 * 
+	 * Note: Casing is to be ignored.
+	 * @return
+	 */
+	@SuppressWarnings("unchecked")
+	public IProperty getClassificationSystemVersion() {
+		return Property.createAsFacade((Map<String, Object>) getSubmodelElement(CLASSIFICATIONSYSTEMVERSIONID));
+	}
+	
+	/**
+	 * Sets class of the associated product or industrial equipment in the classification system. According to the notation of the system.
+	 * 
+	 * Note: Ideally, the Property/valueId is used to reference the IRI/ IRDI of the product class.
+	 * @param id
+	 */
+	public void setProductClassId(Property id) {
+		addSubmodelElement(id);
+	}
+	
+	/**
+	 * Sets class of the associated product or industrial equipment in the classification system. According to the notation of the system.
+	 * 
+	 * Note: Ideally, the Property/valueId is used to reference the IRI/ IRDI of the product class.
+	 * @param id
+	 */
+	public void setProductClassId(String id) {
+		Property idProp = new Property(PRODUCTCLASSID, ValueType.String);
+		idProp.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "https://admin-shell.io/ZVEI/TechnicalData/ProductClassId/1/1", IdentifierType.IRI)));
+		idProp.setValue(id);
+		setProductClassId(idProp);
+	}
+	
+	/**
+	 * Gets class of the associated product or industrial equipment in the classification system. According to the notation of the system.
+	 * 
+	 * Note: Ideally, the Property/valueId is used to reference the IRI/ IRDI of the product class.
+	 * @return
+	 */
+	@SuppressWarnings("unchecked")
+	public IProperty getProductClassId() {
+		return Property.createAsFacade((Map<String, Object>) getSubmodelElement(PRODUCTCLASSID));
+	}
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/technicaldata/submodelelementcollections/productclassifications/ProductClassifications.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/technicaldata/submodelelementcollections/productclassifications/ProductClassifications.java
new file mode 100644
index 0000000..955c34a
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/technicaldata/submodelelementcollections/productclassifications/ProductClassifications.java
@@ -0,0 +1,117 @@
+/*******************************************************************************
+* Copyright (C) 2021 the Eclipse BaSyx Authors
+* 
+* This program and the accompanying materials are made
+* available under the terms of the Eclipse Public License 2.0
+* which is available at https://www.eclipse.org/legal/epl-2.0/
+
+* 
+* SPDX-License-Identifier: EPL-2.0
+******************************************************************************/
+
+package org.eclipse.basyx.submodel.types.technicaldata.submodelelementcollections.productclassifications;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyType;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.facade.SubmodelElementMapCollectionConverter;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
+import org.eclipse.basyx.submodel.types.helper.SubmodelElementRetrievalHelper;
+
+/**
+ * ProductClassifications as described in the Submodel Template AAS Technical Data Document
+ * It is a submodel element collection which contains Product classifications by association with product classes in common classification systems.
+ * 
+ * @author haque
+ *
+ */
+public class ProductClassifications extends SubmodelElementCollection {
+	public static final String IDSHORT = "ProductClassifications";
+	public static final Reference SEMANTICID = new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "https://admin-shell.io/ZVEI/TechnicalData/ProductClassifications/1/1", KeyType.IRI));
+	public static final String PRODUCTCLASSIFICATIONITEMPREFIX = "ProductClassificationItem";
+	
+	/**
+	 * Constructor with default idshort
+	 */
+	public ProductClassifications() {
+		this(IDSHORT);
+	}
+	
+	/**
+	 * Constructor with mandatory attributes
+	 * 
+	 * @param idShort
+	 */
+	public ProductClassifications(String idShort) {
+		super(idShort);
+		setProductClassificationItems(new ArrayList<ProductClassificationItem>());
+	}
+	
+	/**
+	 * Creates a ProductClassifications SMC object from a map
+	 * 
+	 * @param obj a ProductClassifications SMC object as raw map
+	 * @return a ProductClassifications SMC object, that behaves like a facade for the given map
+	 */
+	public static ProductClassifications createAsFacade(Map<String, Object> obj) {
+		if (obj == null) {
+			return null;
+		}
+		
+		if (!isValid(obj)) {
+			throw new MetamodelConstructionException(ProductClassifications.class, obj);
+		}
+		
+		ProductClassifications productClassifications = new ProductClassifications();
+		productClassifications.setMap((Map<String, Object>)SubmodelElementMapCollectionConverter.mapToSmECollection(obj));
+		return productClassifications;
+	}
+	
+	/**
+	 * Check whether all mandatory elements for ProductClassifications SMC
+	 * exist in the map
+	 * 
+	 * @param obj
+	 * 
+	 * @return true/false
+	 */
+	public static boolean isValid(Map<String, Object> obj) {
+		return SubmodelElementCollection.isValid(obj);
+	}
+	
+	/**
+	 * Sets single product classification item by association with product class in a particular classification system or property dictionary
+	 * 
+	 * @param items
+	 */
+	public void setProductClassificationItems(List<ProductClassificationItem> items) {
+		if (items != null && items.size() > 0) {
+			for (ProductClassificationItem item: items) {
+				addSubmodelElement(item);
+			}
+		}
+	}
+	
+	/**
+	 * Gets single product classification item by association with product class in a particular classification system or property dictionary
+	 * 
+	 * @return
+	 */
+	@SuppressWarnings("unchecked")
+	public List<ProductClassificationItem> getProductClassificationItems() {
+		List<ProductClassificationItem> ret = new ArrayList<ProductClassificationItem>();
+		List<ISubmodelElement> elements = SubmodelElementRetrievalHelper.getSubmodelElementsByIdPrefix(PRODUCTCLASSIFICATIONITEMPREFIX, getSubmodelElements());
+		
+		for (ISubmodelElement element: elements) {
+			ret.add(ProductClassificationItem.createAsFacade((Map<String, Object>) element));
+		}
+		return ret;
+	}
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/technicaldata/submodelelementcollections/technicalproperties/TechnicalProperties.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/technicaldata/submodelelementcollections/technicalproperties/TechnicalProperties.java
new file mode 100644
index 0000000..78185f2
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/types/technicaldata/submodelelementcollections/technicalproperties/TechnicalProperties.java
@@ -0,0 +1,229 @@
+/*******************************************************************************
+* Copyright (C) 2021 the Eclipse BaSyx Authors
+* 
+* This program and the accompanying materials are made
+* available under the terms of the Eclipse Public License 2.0
+* which is available at https://www.eclipse.org/legal/epl-2.0/
+
+* 
+* SPDX-License-Identifier: EPL-2.0
+******************************************************************************/
+
+package org.eclipse.basyx.submodel.types.technicaldata.submodelelementcollections.technicalproperties;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyType;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElementCollection;
+import org.eclipse.basyx.submodel.metamodel.facade.SubmodelElementMapCollectionConverter;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
+import org.eclipse.basyx.submodel.types.helper.SubmodelElementRetrievalHelper;
+
+/**
+ * TechnicalProperties as described in the Submodel Template AAS Technical Data Document
+ * 
+ * It is a submodel element collection which contains Individual characteristics that describe the product (industrial equipment) and its technical properties.
+ * 
+ * @author haque
+ *
+ */
+public class TechnicalProperties extends SubmodelElementCollection {
+	public static final String IDSHORT = "TechnicalProperties";
+	public static final String MAINSECTIONPREFIX = "MainSection";
+	public static final String SUBSECTIONPREFIX = "SubSection";
+	public static final String SMENOTDESCRIBEDID = "https://admin-shell.io/SemanticIdNotAvailable/1/1";
+	public static final String MAINSECTIONID = "https://admin-shell.io/ZVEI/TechnicalData/MainSection/1/1";
+	public static final String SUBSECTIONID = "https://admin-shell.io/ZVEI/TechnicalData/SubSection/1/1";
+	public static final Reference SEMANTICID = new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "https://admin-shell.io/ZVEI/TechnicalData/TechnicalProperties/1/1", KeyType.IRI));
+
+	/**
+	 * Constructor with default idShort
+	 */
+	public TechnicalProperties() {
+		this(IDSHORT);
+	}
+	
+	/**
+	 * Constructor with mandatory attributes
+	 * @param idShort
+	 */
+	public TechnicalProperties(String idShort) {
+		super(idShort);
+	}
+	
+	/**
+	 * Creates a TechnicalProperties SMC object from a map
+	 * 
+	 * @param obj a TechnicalProperties SMC object as raw map
+	 * @return a TechnicalProperties SMC object, that behaves like a facade for the given map
+	 */
+	public static TechnicalProperties createAsFacade(Map<String, Object> obj) {
+		if (obj == null) {
+			return null;
+		}
+		
+		if (!isValid(obj)) {
+			throw new MetamodelConstructionException(TechnicalProperties.class, obj);
+		}
+		
+		TechnicalProperties technicalProperties = new TechnicalProperties();
+		technicalProperties.setMap((Map<String, Object>)SubmodelElementMapCollectionConverter.mapToSmECollection(obj));
+		return technicalProperties;
+	}
+	
+	/**
+	 * Check whether all mandatory elements for TechnicalProperties SMC
+	 * exist in the map
+	 * 
+	 * @param obj
+	 * 
+	 * @return true/false
+	 */
+	public static boolean isValid(Map<String, Object> obj) {
+		return SubmodelElementCollection.isValid(obj);
+	}
+	
+	/**
+	 * Sets arbitrary semanticId but defined in a classification system
+	 * 
+	 * Arbitrary SubmodelElement with semanticId possibly referring to a ConceptDescription can be used within the Technical Properties.
+	 * 
+	 * @param elements
+	 */
+	public void setArbitrary(List<SubmodelElement> elements) {
+		if (elements != null && elements.size() > 0) {
+			for (SubmodelElement elem: elements) {
+				addSubmodelElement(elem);	
+			}
+		}
+	}
+	
+	/**
+	 * Gets arbitrary semanticId but defined in a classification system
+	 * 
+	 * Arbitrary SubmodelElement with semanticId possibly referring to a ConceptDescription can be used within the Technical Properties.
+	 *
+	 * @return
+	 */
+	public List<ISubmodelElement> getArbitrary() {
+		return getSubmodelElements()
+				.values().stream()
+				.filter(x -> {
+					String id = x.getSemanticId().getKeys().get(0).getValue();
+					if (id.equals(MAINSECTIONID) || id.equals(SUBSECTIONID) || id.equals(SMENOTDESCRIBEDID)) {
+						return false;
+					} else {
+						return true;
+					}
+				})
+				.collect(Collectors.toList());
+	}
+	
+	/**
+	 * Set arbitrary
+	 * 
+	 * Represents a SubmodelElement that is not described using a common classification system, a consortium specification, an open community standard, a published manufacturer specification or such.
+	 * 
+	 * Note: The idShort of the SubmodelElement can be named accordingly. Constraints concerning the usable characters for idShort shall be respected.
+	 * Note: Only perceivable by human understanding.
+	 * Note: The special case of SME being a SMC is accepted, will be rendered as MainSection/ SubSection accordingly.
+	 * @param elements
+	 */
+	public void setSMENotDescribedBySemanticId(List<SubmodelElement> elements) {
+		if (elements != null && elements.size() > 0) {
+			for (SubmodelElement elem: elements) {
+				addSubmodelElement(elem);	
+			}
+		}
+	}
+	
+	/**
+	 * Get arbitrary
+	 * Represents a SubmodelElement that is not described using a common classification system, a consortium specification, an open community standard, a published manufacturer specification or such.
+	 * 
+	 * Note: The idShort of the SubmodelElement can be named accordingly. Constraints concerning the usable characters for idShort shall be respected.
+	 * Note: Only perceivable by human understanding.
+	 * Note: The special case of SME being a SMC is accepted, will be rendered as MainSection/ SubSection accordingly.
+	 * @return
+	 */
+	public List<ISubmodelElement> getSMENotDescribedBySemanticId() {
+		return getSubmodelElements()
+				.values().stream()
+				.filter(x -> x.getSemanticId().getKeys().get(0).getValue()
+						.equals(SMENOTDESCRIBEDID))
+				.collect(Collectors.toList());
+	}
+	
+	/**
+	 * Sets main subdivision possibility for properties.
+	 * 
+	 * Note: Each Main Section SMC may contain arbitray sets of SubmodelElements, SemanticIdNotAvailable, SubSection.
+	 * @param mainSections
+	 */
+	public void setMainSections(List<SubmodelElementCollection> mainSections) {
+		if (mainSections != null && mainSections.size() > 0) {
+			for (SubmodelElementCollection section: mainSections) {
+				addSubmodelElement(section);	
+			}
+		}
+	}
+	
+	/**
+	 * Gets main subdivision possibility for properties.
+	 * 
+	 * Note: Each Main Section SMC may contain arbitray sets of SubmodelElements, SemanticIdNotAvailable, SubSection.
+	 * 
+	 * @return
+	 */
+	@SuppressWarnings("unchecked")
+	public List<ISubmodelElementCollection> getMainSections() {
+		List<ISubmodelElementCollection> ret = new ArrayList<ISubmodelElementCollection>();
+		List<ISubmodelElement> elements = SubmodelElementRetrievalHelper.getSubmodelElementsByIdPrefix(MAINSECTIONPREFIX, getSubmodelElements());
+		
+		for (ISubmodelElement element: elements) {
+			ret.add(SubmodelElementCollection.createAsFacade((Map<String, Object>) element));
+		}
+		return ret;
+	}
+	
+	/**
+	 * Sets subordinate subdivision possibility for properties.
+	 * 
+	 * Note: Each Sub Section SMC may contain arbitray sets of SubmodelElements, SemanticIdNotAvailable, SubSection.
+	 * @param mainSections
+	 */
+	public void setSubSections(List<SubmodelElementCollection> subSections) {
+		if (subSections != null && subSections.size() > 0) {
+			for (SubmodelElementCollection section: subSections) {
+				addSubmodelElement(section);	
+			}
+		}
+	}
+	
+	/**
+	 * Gets subordinate subdivision possibility for properties.
+	 * 
+	 * Note: Each Sub Section SMC may contain arbitray sets of SubmodelElements, SemanticIdNotAvailable, SubSection.
+	 * 
+	 * @return
+	 */
+	@SuppressWarnings("unchecked")
+	public List<ISubmodelElementCollection> getSubSections() {
+		List<ISubmodelElementCollection> ret = new ArrayList<ISubmodelElementCollection>();
+		List<ISubmodelElement> elements = SubmodelElementRetrievalHelper.getSubmodelElementsByIdPrefix(SUBSECTIONPREFIX, getSubmodelElements());
+		
+		for (ISubmodelElement element: elements) {
+			ret.add(SubmodelElementCollection.createAsFacade((Map<String, Object>) element));
+		}
+		return ret;
+	}
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/connector/JSONConnector.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/connector/JSONConnector.java
index 4b0abcc..6fc5eaa 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/connector/JSONConnector.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/connector/JSONConnector.java
@@ -1,8 +1,18 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.vab.coder.json.connector;
 
-import java.util.ArrayList;
-import java.util.List;
+import java.util.Arrays;
+import java.util.UUID;
 
+import org.eclipse.basyx.submodel.restapi.operation.InvocationRequest;
 import org.eclipse.basyx.vab.coder.json.metaprotocol.IMetaProtocolHandler;
 import org.eclipse.basyx.vab.coder.json.metaprotocol.MetaprotocolHandler;
 import org.eclipse.basyx.vab.coder.json.serialization.DefaultTypeFactory;
@@ -12,6 +22,8 @@
 import org.eclipse.basyx.vab.modelprovider.VABPathTools;
 import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
 import org.eclipse.basyx.vab.protocol.api.IBaSyxConnector;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 
 /**
@@ -24,6 +36,9 @@
  */
 public class JSONConnector implements IModelProvider {
 
+	private static final Logger LOGGER_DEFAULT = LoggerFactory.getLogger(JSONConnector.class);
+	private static final Logger LOGGER_COMMUNICATION = LoggerFactory.getLogger(LOGGER_DEFAULT.getName() + ".MALFORMED");
+	
 	
 	/**
 	 * Reference to Connector backend
@@ -76,24 +91,34 @@
 	
 
 	@Override
-	public Object getModelPropertyValue(String path) throws ProviderException {
+	public Object getValue(String path) throws ProviderException {
 		VABPathTools.checkPathForNull(path);
 
 		// Get element from server
-		String message = provider.getModelPropertyValue(path);
+		String message = provider.getValue(path);
 
 		// De-serialize and verify
-		return metaProtocolHandler.deserialize(message);
+		try {
+			return metaProtocolHandler.deserialize(message);
+		} catch (ProviderException e) {
+			throw e;
+		} catch (RuntimeException e) {
+			String messageCorrelation = UUID.randomUUID().toString();
+			String msg = "Failed to deserialize request for '" + provider.getEndpointRepresentation(path) + "' (" + messageCorrelation + ")";
+			LOGGER_DEFAULT.warn(msg);
+			LOGGER_COMMUNICATION.warn(msg + ": " + message);
+			throw new ProviderException(msg, e);
+		}
 	}
 
 	@Override
-	public void setModelPropertyValue(String path, Object newValue) throws ProviderException {
+	public void setValue(String path, Object newValue) throws ProviderException {
 		VABPathTools.checkPathForNull(path);
 
 		// Serialize value Object
 		String jsonString = serializer.serialize(newValue);
 
-		String message = provider.setModelPropertyValue(path, jsonString);
+		String message = provider.setValue(path, jsonString);
 
 		// De-serialize and verify
 		metaProtocolHandler.deserialize(message);
@@ -140,16 +165,16 @@
 		VABPathTools.checkPathForNull(path);
 
 		// Serialize parameter
-		List<Object> params = new ArrayList<>();
-		for (Object o : parameter) {
-			params.add(o);
+		String jsonString;
+		if (parameter.length == 1 && parameter[0] instanceof InvocationRequest) {
+			jsonString = serializer.serialize(parameter[0]);
+		} else {
+			jsonString = serializer.serialize(Arrays.asList(parameter));
 		}
 
-		String jsonString = serializer.serialize(params);
-
 		String message = provider.invokeOperation(path, jsonString);
 
 		// De-serialize and verify
 		return metaProtocolHandler.deserialize(message);
 	}
-}
\ No newline at end of file
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/metaprotocol/IMetaProtocolHandler.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/metaprotocol/IMetaProtocolHandler.java
index 3c28b2e..634c4b5 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/metaprotocol/IMetaProtocolHandler.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/metaprotocol/IMetaProtocolHandler.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.vab.coder.json.metaprotocol;
 
 import org.eclipse.basyx.vab.exception.provider.ProviderException;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/metaprotocol/Message.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/metaprotocol/Message.java
index d3c036d..a11de57 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/metaprotocol/Message.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/metaprotocol/Message.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.vab.coder.json.metaprotocol;
 
 import java.util.HashMap;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/metaprotocol/MessageType.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/metaprotocol/MessageType.java
index c27d293..fe6cce7 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/metaprotocol/MessageType.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/metaprotocol/MessageType.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.vab.coder.json.metaprotocol;
 
 /**
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/metaprotocol/MetaprotocolHandler.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/metaprotocol/MetaprotocolHandler.java
index 60b832d..09195e3 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/metaprotocol/MetaprotocolHandler.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/metaprotocol/MetaprotocolHandler.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.vab.coder.json.metaprotocol;
 
 import java.util.Collection;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/metaprotocol/Result.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/metaprotocol/Result.java
index 40d0291..4fa9bc0 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/metaprotocol/Result.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/metaprotocol/Result.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.vab.coder.json.metaprotocol;
 
 import java.util.Arrays;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/provider/JSONProvider.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/provider/JSONProvider.java
index e1376ec..1d3c2f7 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/provider/JSONProvider.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/provider/JSONProvider.java
@@ -1,6 +1,17 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.vab.coder.json.provider;
 
-import java.io.PrintWriter;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.charset.StandardCharsets;
 import java.util.Collection;
 
 import org.eclipse.basyx.vab.coder.json.metaprotocol.Result;
@@ -112,12 +123,15 @@
 	 * @param path
 	 * @param resp
 	 */
-	private void sendException(PrintWriter resp, Exception e) throws ProviderException {
+	private void sendException(OutputStream resp, Exception e) throws ProviderException {
 		
 		// Serialize Exception
 		String jsonString = serialize(e);
-
-		resp.write(jsonString);
+		try {
+			resp.write(jsonString.getBytes(StandardCharsets.UTF_8));
+		} catch(IOException innerE) {
+			throw new ProviderException("Failed to send Exception '" + e.getMessage() + "' to client", innerE);
+		}
 		
 		//If the Exception is a ProviderException, just rethrow it
 		if(e instanceof ProviderException) {
@@ -141,7 +155,7 @@
 	 * @throws LostHTTPRequestParameterException 
 	 * @throws ProviderException
 	 */
-	private Object extractParameter(String path, String serializedJSONValue, PrintWriter outputStream) throws MalformedRequestException {
+	private Object extractParameter(String path, String serializedJSONValue, OutputStream outputStream) throws MalformedRequestException {
 		// Return value
 		Object result = null;
 
@@ -161,17 +175,17 @@
 	 * Process a BaSys get operation, return JSON serialized result
 	 * @throws ProviderException 
 	 */
-	public void processBaSysGet(String path, PrintWriter outputStream) throws ProviderException {
+	public void processBaSysGet(String path, OutputStream outputStream) throws ProviderException {
 
 		try {
 			// Get requested value from provider backend
-			Object value = providerBackend.getModelPropertyValue(path);
+			Object value = providerBackend.getValue(path);
 
 			// Serialize as json string - any messages?
 			String jsonString = serializer.serialize(value);
 
 			// Send response
-			outputStream.write(jsonString);
+			outputStream.write(jsonString.getBytes(StandardCharsets.UTF_8));
 		} catch (Exception e) {
 			sendException(outputStream, e);
 		}
@@ -186,7 +200,7 @@
 	 * @param outputStream
 	 * @throws ProviderException 
 	 */
-	public void processBaSysSet(String path, String serializedJSONValue, PrintWriter outputStream) throws ProviderException {
+	public void processBaSysSet(String path, String serializedJSONValue, OutputStream outputStream) throws ProviderException {
 		
 		// Try to set value of BaSys VAB element
 		try {
@@ -195,10 +209,10 @@
 			Object parameter = extractParameter(path, serializedJSONValue, outputStream);
 
 			// Set the value of the element
-			providerBackend.setModelPropertyValue(path, parameter);
+			providerBackend.setValue(path, parameter);
 
 			// Send response
-			outputStream.write("");
+			outputStream.write("".getBytes(StandardCharsets.UTF_8));
 
 		} catch (Exception e) {
 			sendException(outputStream, e);
@@ -211,7 +225,7 @@
 	 * @throws ProviderException 
 	 */
 	@SuppressWarnings("unchecked")
-	public void processBaSysInvoke(String path, String serializedJSONValue, PrintWriter outputStream) throws ProviderException {
+	public void processBaSysInvoke(String path, String serializedJSONValue, OutputStream outputStream) throws ProviderException {
 
 		try {
 			
@@ -244,7 +258,7 @@
 			String jsonString = serializer.serialize(result);
 			
 			// Send response
-			outputStream.write(jsonString);
+			outputStream.write(jsonString.getBytes(StandardCharsets.UTF_8));
 
 		} catch (Exception e) {
 			sendException(outputStream, e);
@@ -260,7 +274,7 @@
 	 * @param outputStream
 	 * @throws ProviderException 
 	 */
-	public void processBaSysDelete(String path, String serializedJSONValue, PrintWriter outputStream) throws ProviderException {
+	public void processBaSysDelete(String path, String serializedJSONValue, OutputStream outputStream) throws ProviderException {
 		
 		try {
 
@@ -275,7 +289,7 @@
 			}
 
 			// Send response
-			outputStream.write("");
+			outputStream.write("".getBytes(StandardCharsets.UTF_8));
 
 		} catch (Exception e) {
 			sendException(outputStream, e);
@@ -291,7 +305,7 @@
 	 * @param outputStream
 	 * @throws ProviderException 
 	 */
-	public void processBaSysCreate(String path, String serializedJSONValue, PrintWriter outputStream) throws ProviderException {
+	public void processBaSysCreate(String path, String serializedJSONValue, OutputStream outputStream) throws ProviderException {
 
 		try {
 			// Deserialize json body. 
@@ -301,7 +315,7 @@
 			providerBackend.createValue(path, parameter);
 
 			// Send response
-			outputStream.write("");
+			outputStream.write("".getBytes(StandardCharsets.UTF_8));
 		} catch (Exception e) {
 			sendException(outputStream, e);
 		}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/serialization/DefaultTypeFactory.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/serialization/DefaultTypeFactory.java
index c7fcd3f..3066bf8 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/serialization/DefaultTypeFactory.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/serialization/DefaultTypeFactory.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.vab.coder.json.serialization;
 
 import java.util.ArrayList;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/serialization/GSONTools.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/serialization/GSONTools.java
index 34f1eec..fde9ef9 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/serialization/GSONTools.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/serialization/GSONTools.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.vab.coder.json.serialization;
 
 import java.io.ByteArrayInputStream;
@@ -7,6 +16,7 @@
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
 import java.io.Serializable;
+import java.math.BigInteger;
 import java.util.Base64;
 import java.util.Collection;
 import java.util.Map;
@@ -19,6 +29,7 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.gson.Gson;
 import com.google.gson.JsonArray;
 import com.google.gson.JsonElement;
 import com.google.gson.JsonNull;
@@ -59,6 +70,16 @@
 	 * Type factory
 	 */
 	protected GSONToolsFactory toolsFactory = null;
+	
+	/**
+	 * Flag to remove null values from serialized JSON
+	 */
+	private boolean removeNull = true;
+	
+	/**
+	 * Flag to remove empty arrays from serialized JSON 
+	 */
+	private boolean removeEmpty = false;
 
 	/**
 	 * Constructor
@@ -67,6 +88,15 @@
 		// Store factory reference
 		toolsFactory = factory;
 	}
+	
+	/**
+	 * Constructor
+	 */
+	public GSONTools(GSONToolsFactory factory, boolean removeNull, boolean removeEmpty) {
+		this(factory);
+		this.removeNull = removeNull;
+		this.removeEmpty = removeEmpty;
+	}
 
 	/**
 	 * Set factory instance
@@ -85,7 +115,14 @@
 	@Override
 	public String serialize(Object obj) {
 		JsonElement elem = serializeObject(obj);
-		return elem.toString();
+		// Removing null value if the removeNull flag is on
+		if (removeNull) {
+			// Gson#toJson removes null automatically
+			Gson gson = new Gson();
+			return gson.toJson(elem);
+		} else {
+			return elem.toString();
+		}
 	}
 
 	/**
@@ -98,7 +135,7 @@
 	private JsonElement serializeObject(Object obj) {
 		if (obj == null) {
 			return JsonNull.INSTANCE;
-		} else if (obj.getClass().isPrimitive() || isWrapperType(obj.getClass()) || obj instanceof String) {
+		} else if (obj.getClass().isPrimitive() || isWrapperType(obj.getClass()) || obj instanceof String || obj instanceof Number) {
 			return serializePrimitive(obj);
 		} else if (obj instanceof Map<?, ?>) {
 			return serializeMap((Map<String, Object>) obj);
@@ -149,7 +186,19 @@
 			if (primitive.getAsString().contains(".")) {
 				return primitive.getAsDouble();
 			} else {
-				return primitive.getAsInt();
+				// Get value as Big integer
+				BigInteger tmp= primitive.getAsBigInteger();
+				if (BigInteger.valueOf(Integer.MAX_VALUE).compareTo(tmp) >= 0 && BigInteger.valueOf(Integer.MIN_VALUE).compareTo(tmp) <= 0) {
+					// convert to int
+					return primitive.getAsInt();
+				} else if (BigInteger.valueOf(Long.MAX_VALUE).compareTo(tmp) >= 0 && BigInteger.valueOf(Long.MIN_VALUE).compareTo(tmp) <= 0) {
+					// convert to long
+					return primitive.getAsLong();
+				} else {
+					// for types NonNegativeInteger, NonPositiveInteger, NegativeInteger,
+					// PositiveInteger
+					return tmp;
+				}
 			}
 		} else if (primitive.isBoolean()) {
 			return primitive.getAsBoolean();
@@ -158,6 +207,7 @@
 		}
 	}
 
+
 	/**
 	 * Serializes either string, number or boolean to a JsonPrimitive
 	 * 
@@ -219,7 +269,11 @@
 	private JsonObject serializeMap(Map<String, Object> map) {
 		JsonObject obj = new JsonObject();
 		for (Entry<String, Object> entry : map.entrySet()) {
-			obj.add(entry.getKey(), serializeObject(entry.getValue()));
+			Object value = entry.getValue();
+			// Remove empty list if removeEmpty flag is on
+            if (!removeEmpty || !(value instanceof Collection<?> && ((Collection<?>)value).isEmpty())) {
+            	obj.add(entry.getKey(), serializeObject(value));
+        	}
 		}
 		return obj;
 	}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/serialization/GSONToolsFactory.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/serialization/GSONToolsFactory.java
index 31dd4b6..ee0685b 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/serialization/GSONToolsFactory.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/serialization/GSONToolsFactory.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.vab.coder.json.serialization;
 
 import java.util.Collection;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/serialization/Serializer.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/serialization/Serializer.java
index 523387f..1ea9f8b 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/serialization/Serializer.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/serialization/Serializer.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.vab.coder.json.serialization;
 
 /**
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/directory/api/IVABDirectoryService.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/directory/api/IVABDirectoryService.java
deleted file mode 100644
index 17d51a8..0000000
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/directory/api/IVABDirectoryService.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package org.eclipse.basyx.vab.directory.api;
-
-/**
- * Directory service SDK interface.
- * 
- * @author kuhn
- *
- */
-public interface IVABDirectoryService {
-
-	
-	/**
-	 * Add a mapping to directory
-	 */
-	public IVABDirectoryService addMapping(String key, String value);
-
-	
-	/**
-	 * Remove a mapping from directory
-	 */
-	public void removeMapping(String key);
-	
-
-	/**
-	 * Lookup method maps key "id" to value
-	 */
-	public String lookup(String id);
-}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/directory/memory/InMemoryDirectory.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/directory/memory/InMemoryDirectory.java
deleted file mode 100644
index a3ee350..0000000
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/directory/memory/InMemoryDirectory.java
+++ /dev/null
@@ -1,82 +0,0 @@
-package org.eclipse.basyx.vab.directory.memory;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.eclipse.basyx.vab.directory.api.IVABDirectoryService;
-import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
-
-
-
-/**
- * Implement a in memory directory
- * 
- * @author kuhn
- *
- */
-public class InMemoryDirectory implements IVABDirectoryService {
-
-	
-	/**
-	 * Map that stores key/value mappings
-	 */
-	protected Map<String, Object> keyToValue = new HashMap<>();
-	
-	
-		
-	
-	/**
-	 * Default constructor
-	 */
-	public InMemoryDirectory() {
-		// Do nothing
-	}
-	
-	
-	/**
-	 * Constructor that accepts initial entries
-	 */
-	public InMemoryDirectory(Map<String, String> addedValues) {
-		keyToValue.putAll(addedValues);
-	}
-	
-	
-	
-	/**
-	 * Add a mapping to directory
-	 */
-	@Override
-	public IVABDirectoryService addMapping(String key, String value) {
-		keyToValue.put(key, value);
-		
-		// Return 'this' instance
-		return this;
-	}
-
-	/**
-	 * Add several mappings to directory
-	 */
-	public void addMappings(Map<String, String> mappings) {
-		keyToValue.putAll(mappings);
-	}
-	
-	/**
-	 * Remove a mapping from directory
-	 */
-	@Override
-	public void removeMapping(String key) {
-		keyToValue.remove(key);
-	}
-	
-	/**
-	 * Lookup method
-	 */
-	@Override
-	public String lookup(String id) {
-		if(keyToValue.containsKey(id)) {
-			return (String) keyToValue.get(id);
-		} else {
-			throw new ResourceNotFoundException("No entry exists for key " + id);
-		}
-	}
-}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/directory/proxy/VABDirectoryProxy.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/directory/proxy/VABDirectoryProxy.java
deleted file mode 100644
index 9741496..0000000
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/directory/proxy/VABDirectoryProxy.java
+++ /dev/null
@@ -1,66 +0,0 @@
-package org.eclipse.basyx.vab.directory.proxy;
-
-import org.eclipse.basyx.vab.coder.json.connector.JSONConnector;
-import org.eclipse.basyx.vab.directory.api.IVABDirectoryService;
-import org.eclipse.basyx.vab.exception.provider.ProviderException;
-import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
-import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnector;
-
-public class VABDirectoryProxy implements IVABDirectoryService {
-	/**
-	 * Store the URL of the registry of this proxy
-	 */
-	protected IModelProvider provider;
-
-	/**
-	 * Constructor for a generic VAB directory proxy based on a HTTP connection
-	 * 
-	 * @param directoryUrl
-	 *            The endpoint of the registry with a HTTP-REST interface
-	 */
-	public VABDirectoryProxy(String directoryUrl) {
-		this(new VABElementProxy("", new JSONConnector(new HTTPConnector(directoryUrl))));
-	}
-	
-	/**
-	 * Constructor for a generic VAB directory based on the registry model provider
-	 * 
-	 * @param provider
-	 *            A model provider for the actual registry
-	 */
-	public VABDirectoryProxy(IModelProvider provider) {
-		this.provider = provider;
-	}
-
-	/**
-	 * Adds a single entry to the directory
-	 */
-	@Override
-	public IVABDirectoryService addMapping(String key, String value) {
-		provider.createValue(key, value);
-		return this;
-	}
-
-	/**
-	 * Deletes an entry from the directory
-	 */
-	@Override
-	public void removeMapping(String key) {
-		provider.deleteValue(key);
-	}
-
-	/**
-	 * Returns a single entry in the directory
-	 */
-	@Override
-	public String lookup(String id) {
-		Object response = provider.getModelPropertyValue(id);
-		
-		if (response instanceof String) {
-			return (String) response;
-		} else {
-			throw new ProviderException("Lookup returned unexpected object: " + response);
-		}
-	}
-}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/directory/restapi/DirectoryModelProvider.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/directory/restapi/DirectoryModelProvider.java
deleted file mode 100644
index 0d06c5c..0000000
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/directory/restapi/DirectoryModelProvider.java
+++ /dev/null
@@ -1,69 +0,0 @@
-package org.eclipse.basyx.vab.directory.restapi;
-
-import org.eclipse.basyx.vab.directory.api.IVABDirectoryService;
-import org.eclipse.basyx.vab.directory.memory.InMemoryDirectory;
-import org.eclipse.basyx.vab.exception.provider.ProviderException;
-import org.eclipse.basyx.vab.modelprovider.VABPathTools;
-import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
-
-/**
- * Connects an arbitrary IVABDirectoryService implementation to the VAB
- * 
- * @author schnicke
- */
-
-public class DirectoryModelProvider implements IModelProvider {
-
-	private IVABDirectoryService directory;
-
-	/**
-	 * Creates a DirectoryModelProvider wrapping an IVABDirectoryService
-	 * 
-	 * @param directory
-	 */
-	public DirectoryModelProvider(IVABDirectoryService directory) {
-		super();
-		this.directory = directory;
-	}
-
-	/**
-	 * Creates a default DirectoryModelProvider wrapping an InMemoryDirectory
-	 */
-	public DirectoryModelProvider() {
-		this(new InMemoryDirectory());
-	}
-
-	@Override
-	public Object getModelPropertyValue(String path) throws ProviderException {
-		path = VABPathTools.stripSlashes(path);
-		return directory.lookup(path);
-	}
-
-	@Override
-	public void setModelPropertyValue(String path, Object newValue) throws ProviderException {
-		throw new RuntimeException("Set not supported by VAB Directory");
-	}
-
-	@Override
-	public void createValue(String path, Object newEntity) throws ProviderException {
-		path = VABPathTools.stripSlashes(path);
-		directory.addMapping(path, (String) newEntity);
-	}
-
-	@Override
-	public void deleteValue(String path) throws ProviderException {
-		path = VABPathTools.stripSlashes(path);
-		directory.removeMapping(path);
-	}
-
-	@Override
-	public void deleteValue(String path, Object obj) throws ProviderException {
-		throw new RuntimeException("Delete with parameter not supported by VAB Directory");
-	}
-
-	@Override
-	public Object invokeOperation(String path, Object... parameter) throws ProviderException {
-		throw new RuntimeException("Invoke not supported by VAB Directory");
-	}
-
-}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/AtomicTransactionFailedException.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/AtomicTransactionFailedException.java
index 8e5a003..07ac87d 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/AtomicTransactionFailedException.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/AtomicTransactionFailedException.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.vab.exception;
 
 public class AtomicTransactionFailedException extends Exception {
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/FeatureNotImplementedException.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/FeatureNotImplementedException.java
index 27f0dcc..5690bf0 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/FeatureNotImplementedException.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/FeatureNotImplementedException.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.vab.exception;
 
 
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/LostHTTPRequestParameterException.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/LostHTTPRequestParameterException.java
index 63d1b72..35130dd 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/LostHTTPRequestParameterException.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/LostHTTPRequestParameterException.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.vab.exception;
 
 public class LostHTTPRequestParameterException extends Exception {
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/ReadOnlyException.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/ReadOnlyException.java
index 498bfca..e9b3dc6 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/ReadOnlyException.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/ReadOnlyException.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.vab.exception;
 
 public class ReadOnlyException extends Exception {
@@ -12,7 +21,7 @@
 	 */
 	public ReadOnlyException(String name) {
 		// Store message
-		message = "The SubModel "+name+" is frozen.";
+		message = "The Submodel "+name+" is frozen.";
 	}
 	
 	
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/TypeMismatchException.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/TypeMismatchException.java
index c9e36da..01a4808 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/TypeMismatchException.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/TypeMismatchException.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.vab.exception;
 
 public class TypeMismatchException extends Exception {
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/UnknownElementTypeException.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/UnknownElementTypeException.java
index 7114694..4e6fbf6 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/UnknownElementTypeException.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/UnknownElementTypeException.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.vab.exception;
 
 
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/provider/MalformedRequestException.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/provider/MalformedRequestException.java
index 02f92a0..1137cd3 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/provider/MalformedRequestException.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/provider/MalformedRequestException.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.vab.exception.provider;
 
 /**
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/provider/NotAnInvokableException.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/provider/NotAnInvokableException.java
index 58f54d5..62d87fe 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/provider/NotAnInvokableException.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/provider/NotAnInvokableException.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.vab.exception.provider;
 
 /**
@@ -26,4 +35,4 @@
 	public NotAnInvokableException(Exception e) {
 		super(e);
 	}
-}
\ No newline at end of file
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/provider/ProviderException.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/provider/ProviderException.java
index 4544210..8eb45b2 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/provider/ProviderException.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/provider/ProviderException.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.vab.exception.provider;
 
 /**
@@ -35,6 +44,12 @@
 	}
 
 
+	public ProviderException(String message, Throwable cause) {
+		super(cause);
+		this.message = message;
+	}
+
+
 	/**
 	 * Return detailed message
 	 */
@@ -42,4 +57,4 @@
 	public String getMessage() {
 		return message;
 	}
-}
\ No newline at end of file
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/provider/ResourceAlreadyExistsException.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/provider/ResourceAlreadyExistsException.java
index 5289ae0..6b6a589 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/provider/ResourceAlreadyExistsException.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/provider/ResourceAlreadyExistsException.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.vab.exception.provider;
 
 /**
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/provider/ResourceNotFoundException.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/provider/ResourceNotFoundException.java
index 9c58147..07e64e2 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/provider/ResourceNotFoundException.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/provider/ResourceNotFoundException.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.vab.exception.provider;
 
 
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/provider/WrongNumberOfParametersException.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/provider/WrongNumberOfParametersException.java
new file mode 100644
index 0000000..32bff37
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/exception/provider/WrongNumberOfParametersException.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.vab.exception.provider;
+
+import java.util.Collection;
+
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperationVariable;
+
+public class WrongNumberOfParametersException extends MalformedRequestException {
+	/**
+	 * Version information for serialized instances
+	 */
+	private static final long serialVersionUID = 1L;
+	public WrongNumberOfParametersException(String operationIdShort, Collection<IOperationVariable> expected, Object... actual) {
+		super(constructErrorMessage(operationIdShort, expected, actual));
+	}
+
+	private static String constructErrorMessage(String operationIdShort, Collection<IOperationVariable> expected, Object... actual) {
+		return "Operation with idShort " + operationIdShort + " was called using the wrong number of parameters. Expected size: " + expected.size() + ", actual: " + actual.length;
+	}
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/factory/java/ModelProxyFactory.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/factory/java/ModelProxyFactory.java
index 7c33ed7..705571a 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/factory/java/ModelProxyFactory.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/factory/java/ModelProxyFactory.java
@@ -1,9 +1,18 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.vab.factory.java;
 
 import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
 import org.eclipse.basyx.vab.modelprovider.VABPathTools;
 import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
-import org.eclipse.basyx.vab.protocol.api.IConnectorProvider;
+import org.eclipse.basyx.vab.protocol.api.IConnectorFactory;
 
 /**
  * A factory for creating model providers out of addresses with multiple endpoints included.
@@ -12,10 +21,10 @@
  *
  */
 public class ModelProxyFactory {
-	private IConnectorProvider connectorProvider;
+	private IConnectorFactory connectorFactory;
 
-	public ModelProxyFactory(IConnectorProvider connectorProvider) {
-		this.connectorProvider = connectorProvider;
+	public ModelProxyFactory(IConnectorFactory connectorFactory) {
+		this.connectorFactory = connectorFactory;
 	}
 	
 	/**
@@ -27,7 +36,7 @@
 	public VABElementProxy createProxy(String path) {
 		// Create a model provider for the first endpoint
 		String addressEntry = VABPathTools.getFirstEndpoint(path);
-		IModelProvider provider = connectorProvider.getConnector(addressEntry);
+		IModelProvider provider = connectorFactory.getConnector(addressEntry);
 		
 		// Return a proxy for the whole path using the connector to the first endpoint
 		String subPath = VABPathTools.removeFirstEndpoint(path);
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/factory/xml/VABXmlProviderFactory.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/factory/xml/VABXmlProviderFactory.java
index 4036244..4391edf 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/factory/xml/VABXmlProviderFactory.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/factory/xml/VABXmlProviderFactory.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.vab.factory.xml;
 
 import org.eclipse.basyx.vab.modelprovider.map.VABMapProvider;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/factory/xml/XmlParser.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/factory/xml/XmlParser.java
index ac14dc2..adef422 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/factory/xml/XmlParser.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/factory/xml/XmlParser.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.vab.factory.xml;
 
 import java.io.IOException;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/gateway/ConnectorProviderMapper.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/gateway/ConnectorProviderMapper.java
index d90db4a..35fd2ab 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/gateway/ConnectorProviderMapper.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/gateway/ConnectorProviderMapper.java
@@ -1,10 +1,19 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.vab.gateway;
 
 import java.util.HashMap;
 import java.util.Map;
 
 import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
-import org.eclipse.basyx.vab.protocol.api.IConnectorProvider;
+import org.eclipse.basyx.vab.protocol.api.IConnectorFactory;
 
 /**
  * Maps an incoming address to an IConnectorProvider based on the protocol used
@@ -15,9 +24,9 @@
  * @author schnicke
  *
  */
-public class ConnectorProviderMapper implements IConnectorProvider {
+public class ConnectorProviderMapper implements IConnectorFactory {
 
-	private Map<String, IConnectorProvider> providerMap = new HashMap<>();
+	private Map<String, IConnectorFactory> providerMap = new HashMap<>();
 
 	/**
 	 * 
@@ -26,7 +35,7 @@
 	 *            <i>basyx://</i>
 	 * @param provider
 	 */
-	public void addConnectorProvider(String prefix, IConnectorProvider provider) {
+	public void addConnectorProvider(String prefix, IConnectorFactory provider) {
 		providerMap.put(prefix, provider);
 	}
 
@@ -47,7 +56,7 @@
 	 */
 	private String getPrefix(String addr) {
 		String prefix = addr.split("//")[0];
-		return prefix.replace(":", "");
+		return prefix.replaceFirst(":", "");
 	}
 
 }
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/gateway/DelegatingModelProvider.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/gateway/DelegatingModelProvider.java
index deff24d..c055d63 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/gateway/DelegatingModelProvider.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/gateway/DelegatingModelProvider.java
@@ -1,9 +1,18 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.vab.gateway;
 
 import org.eclipse.basyx.vab.exception.provider.ProviderException;
 import org.eclipse.basyx.vab.factory.java.ModelProxyFactory;
 import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
-import org.eclipse.basyx.vab.protocol.api.IConnectorProvider;
+import org.eclipse.basyx.vab.protocol.api.IConnectorFactory;
 
 /**
  * IModelProvider that delegates all calls to a Connector to enable gateway
@@ -17,19 +26,19 @@
 	// Provider that provides the connectors
 	private ModelProxyFactory proxyFactory;
 
-	public DelegatingModelProvider(IConnectorProvider connectorProvider) {
+	public DelegatingModelProvider(IConnectorFactory connectorFactory) {
 		super();
-		this.proxyFactory = new ModelProxyFactory(connectorProvider);
+		this.proxyFactory = new ModelProxyFactory(connectorFactory);
 	}
 
 	@Override
-	public Object getModelPropertyValue(String path) throws ProviderException {
-		return getProvider(path).getModelPropertyValue("");
+	public Object getValue(String path) throws ProviderException {
+		return getProvider(path).getValue("");
 	}
 
 	@Override
-	public void setModelPropertyValue(String path, Object newValue) throws ProviderException {
-		getProvider(path).setModelPropertyValue("", newValue);
+	public void setValue(String path, Object newValue) throws ProviderException {
+		getProvider(path).setValue("", newValue);
 	}
 
 	@Override
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/manager/VABConnectionManager.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/manager/VABConnectionManager.java
index 9781e42..9760e34 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/manager/VABConnectionManager.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/manager/VABConnectionManager.java
@@ -1,9 +1,18 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.vab.manager;
 
-import org.eclipse.basyx.vab.directory.api.IVABDirectoryService;
 import org.eclipse.basyx.vab.factory.java.ModelProxyFactory;
 import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
-import org.eclipse.basyx.vab.protocol.api.IConnectorProvider;
+import org.eclipse.basyx.vab.protocol.api.IConnectorFactory;
+import org.eclipse.basyx.vab.registry.api.IVABRegistryService;
 
 
 
@@ -18,13 +27,13 @@
 	/**
 	 * Directory service reference
 	 */
-	protected IVABDirectoryService directoryService = null;
+	protected IVABRegistryService directoryService = null;
 
 	
 	/**
 	 * Store connection providers
 	 */
-	protected IConnectorProvider connectorProvider = null;
+	protected IConnectorFactory connectorFactory = null;
 	
 	/**
 	 * Factory for creating proxies for addresses with multiple endpoints
@@ -38,12 +47,12 @@
 	 * @param providerProvider
 	 *            used to get the appropriate connector for the selected address
 	 */
-	public VABConnectionManager(IVABDirectoryService networkDirectoryService, IConnectorProvider providerProvider) {
+	public VABConnectionManager(IVABRegistryService networkDirectoryService, IConnectorFactory providerProvider) {
 		// Set directory service reference
 		directoryService = networkDirectoryService;
 
 		// Set connector reference
-		this.connectorProvider = providerProvider;
+		this.connectorFactory = providerProvider;
 		
 		// Set proxy factory
 		this.proxyFactory = new ModelProxyFactory(providerProvider);
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/model/VABModelMap.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/model/VABModelMap.java
index c5cb3aa..7acec69 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/model/VABModelMap.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/model/VABModelMap.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.vab.model;
 
 import java.util.Collection;
@@ -5,6 +14,7 @@
 import java.util.Map;
 import java.util.Set;
 
+import org.eclipse.basyx.submodel.metamodel.connected.ConnectedElement;
 import org.eclipse.basyx.vab.support.TypeDestroyer;
 
 /**
@@ -23,7 +33,7 @@
 */
 
 public class VABModelMap<V extends Object> implements Map<String, V> {
-	Map<String, V> map;
+	protected Map<String, V> map;
 
 	/**
 	 * Default constructor
@@ -183,6 +193,12 @@
 		return result;
 	}
 
+	/**
+	 * VABModelMaps are assumed to be equal iff they are containing the same data
+	 * independent of the used containers. <br>
+	 * In consequence, it does not matter if a collection is represented as Set or
+	 * as List, as long as the same elements are contained.
+	 */
 	@SuppressWarnings("unchecked")
 	@Override
 	public boolean equals(Object obj) {
@@ -190,6 +206,9 @@
 			return true;
 		if (obj == null)
 			return false;
+		if (obj instanceof ConnectedElement) {
+			obj = ((ConnectedElement) obj).getElemLive();
+		}
 		if (!Map.class.isAssignableFrom(obj.getClass()))
 			return false;
 
@@ -199,14 +218,15 @@
 		Map<String, Object> otherMap = TypeDestroyer.destroyType(otherVAB);
 
 		if (map == null) {
-			if (otherMap != null)
-				return false;
+			return otherMap == null;
 		} else {
 			Map<String, Object> thisMap = TypeDestroyer.destroyType((Map<String, Object>) map);
-			if (!thisMap.equals(otherMap)) {
-				return false;
-			}
+			return thisMap.equals(otherMap);
 		}
-		return true;
+	}
+
+	@Override
+	public String toString() {
+		return map.toString();
 	}
 }
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/VABElementProxy.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/VABElementProxy.java
index 8750768..c70f149 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/VABElementProxy.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/VABElementProxy.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.vab.modelprovider;
 
 import org.eclipse.basyx.vab.exception.provider.ProviderException;
@@ -47,10 +56,10 @@
 	 * Read VAB element value
 	 */
 	@Override
-	public Object getModelPropertyValue(String elementPath) throws ProviderException {
+	public Object getValue(String elementPath) throws ProviderException {
 		// Get element from server
 		try {
-			return provider.getModelPropertyValue(constructPath(elementPath));
+			return provider.getValue(constructPath(elementPath));
 		} catch (ProviderException e) {
 			throw e;
 		} catch (Exception e) {
@@ -65,11 +74,11 @@
 	 * If the element does not exist it will be created<br />
 	 */
 	@Override
-	public void setModelPropertyValue(String elementPath, Object newValue) throws ProviderException {
+	public void setValue(String elementPath, Object newValue) throws ProviderException {
 		// Set property value
 		try {
 			// Change element on server
-			provider.setModelPropertyValue(constructPath(elementPath), newValue);
+			provider.setValue(constructPath(elementPath), newValue);
 		} catch (ProviderException e) {
 			throw e;
 		} catch (Exception e) {
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/VABPathTools.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/VABPathTools.java
index 720b5b7..6657bba 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/VABPathTools.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/VABPathTools.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.vab.modelprovider;
 
 import java.io.UnsupportedEncodingException;
@@ -6,6 +15,7 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation;
 import org.eclipse.basyx.vab.exception.provider.MalformedRequestException;
 
 /**
@@ -229,10 +239,10 @@
 	}
 
 	/**
-	 * Check if the path to an VAB elements leads to an operation. In this case, the
-	 * element path conforms to /aas/submodels/{subModelId}/operations
+	 * Check if the path to an VAB elements leads to the invocation of an operation. In this case, the
+	 * element path conforms to /aas/submodels/{subModelId}/submodelElements/{operationId}/invoke
 	 */
-	public static boolean isOperationPath(String path) {
+	public static boolean isOperationInvokationPath(String path) {
 		// null-Paths are no operation paths
 		if (path == null) {
 			return false;
@@ -240,16 +250,18 @@
 
 		// Split path
 		String[] pathElements = splitPath(path);
-
-		// Look for the 'operation' element inside the path
-		for (String s : pathElements) {
-			if (s.equals("operations")) {
-				return true;
-			}
+		
+		if(pathElements.length == 0) {
+			return false;
 		}
 
-		// No operation
-		return false;
+		// Check if last path element is "invoke" or "operations" is contained anywhere
+		return pathElements[pathElements.length - 1].startsWith(Operation.INVOKE) || isOperationPath(path);
+	}
+
+	private static boolean isOperationPath(String path) {
+		String lowerCasePath = path.toLowerCase();
+		return lowerCasePath.startsWith("operations/") || path.toLowerCase().contains("/operations/");
 	}
 
 	/**
@@ -361,4 +373,77 @@
 			throw new MalformedRequestException("Path is not allowed to be null");
 		}
 	}
+	
+	/**
+	 * Strips the last path element if it is "invoke"
+	 * 
+	 * @param path
+	 * @return path without last element "invoke" or unchanged path
+	 */
+	public static String stripInvokeFromPath(String path) {
+		
+		if(path == null)
+			return null;
+		
+		if(getLastElement(path).startsWith(Operation.INVOKE)) {
+			return getParentPath(path);
+		}
+		
+		return path;
+	}
+	
+	/**
+	 * Gets the path from a URL
+	 * e.g "http://localhost:8080/path/to/test.file" results in "/path/to/test.file"
+	 * 
+	 * @param url
+	 * @return the path from the URL
+	 */
+	public static String getPathFromURL(String url) {
+		if(url == null) {
+			return null;
+		}
+		
+		if(url.contains("://")) {
+			
+			// Find the ":" and and remove the "http://" from the url
+			int index = url.indexOf(":") + 3;
+			url = url.substring(index);
+			
+			// Find the first "/" from the URL (now without the "http://") and remove everything before that
+			index = url.indexOf("/");
+			url = url.substring(index);
+			
+			// Recursive call to deal with more than one server parts 
+			// (e.g. basyx://127.0.0.1:6998//https://localhost/test/)
+			return getPathFromURL(url);
+		} else {
+			// Make sure the path has a / at the start
+			if(!url.startsWith("/")) {
+				url = "/" + url;
+			}
+			return url;
+		}
+	}
+
+	/**
+	 * Harmonizes a path so that it will always and with the suffix and no ending
+	 * slash (even if the suffix contains one).
+	 * 
+	 * @param path
+	 *            to harmonize
+	 * @param suffix
+	 *            to check for existance and append if necessary
+	 * @return harmonized path
+	 */
+	public static String harmonizePathWithSuffix(String path, String suffix) {
+		String strippedPath = stripSlashes(path);
+		String strippedSuffix = stripSlashes(suffix);
+
+		if (strippedPath.endsWith("/" + strippedSuffix)) {
+			return strippedPath;
+		} else {
+			return VABPathTools.concatenatePaths(strippedPath, strippedSuffix);
+		}
+	}
 }
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/api/IModelProvider.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/api/IModelProvider.java
index 4d98c75..36c89be 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/api/IModelProvider.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/api/IModelProvider.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.vab.modelprovider.api;
 
 import org.eclipse.basyx.vab.exception.provider.ProviderException;
@@ -17,7 +26,7 @@
 	 *            Path to the requested value
 	 * @return Object type is assumed to be [Integer | ... | Collection]
 	 */
-	public Object getModelPropertyValue(String path) throws ProviderException;
+	public Object getValue(String path) throws ProviderException;
 
 	/**
 	 * Sets or overrides existing value in a given path
@@ -27,7 +36,7 @@
 	 * @param newValue
 	 *            Updated value
 	 */
-	public void setModelPropertyValue(String path, Object newValue) throws ProviderException;
+	public void setValue(String path, Object newValue) throws ProviderException;
 
 	/**
 	 * Create a new value under the given path
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/consistency/ConsistencyProvider.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/consistency/ConsistencyProvider.java
index 1875d48..04b3a3f 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/consistency/ConsistencyProvider.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/consistency/ConsistencyProvider.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.vab.modelprovider.consistency;
 
 import org.eclipse.basyx.vab.exception.provider.ProviderException;
@@ -50,14 +59,14 @@
 	}
 
 	@Override
-	public Object getModelPropertyValue(String path) throws ProviderException {
+	public Object getValue(String path) throws ProviderException {
 
 		if (path.endsWith("/frozen")) {
 			return this.frozen;
 		} else if (path.endsWith("/clock")) {
 			return this.clock;
 		} else {
-			return providerBackend.getModelPropertyValue(path);
+			return providerBackend.getValue(path);
 		}
 	}
 
@@ -70,7 +79,7 @@
 	 * @throws Exception
 	 */
 	@Override
-	public void setModelPropertyValue(String path, Object newValue) throws ProviderException {
+	public void setValue(String path, Object newValue) throws ProviderException {
 
 		if (path.endsWith("/frozen")) {
 
@@ -83,7 +92,7 @@
 			incrementClock();
 
 			// Set the value of the element
-			providerBackend.setModelPropertyValue(path, newValue);
+			providerBackend.setValue(path, newValue);
 
 		} else {
 			throw new ProviderException("Value " + path + " is read only");
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/filesystem/FileSystemProvider.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/filesystem/FileSystemProvider.java
index bf25e8a..9006681 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/filesystem/FileSystemProvider.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/filesystem/FileSystemProvider.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.vab.modelprovider.filesystem;
 
 import java.io.IOException;
@@ -324,7 +333,7 @@
 	}
 
 	@Override
-	public synchronized Object getModelPropertyValue(String path) throws ProviderException {
+	public synchronized Object getValue(String path) throws ProviderException {
 		path = unifyPath(path);
 		String directory = VABPathTools.getParentPath(path);
 		String fileName = VABPathTools.getLastElement(path);
@@ -375,7 +384,7 @@
 	 */
 	@Override
 	@SuppressWarnings("unchecked")
-	public synchronized void setModelPropertyValue(String path, Object newValue) throws ProviderException {
+	public synchronized void setValue(String path, Object newValue) throws ProviderException {
 		path = unifyPath(path);
 		String fileName = VABPathTools.getLastElement(path);
 		String fullPath = rootDir + "/" + path;
@@ -566,4 +575,4 @@
 		throw new MalformedRequestException("Invoke not supported by filesystem");
 	}
 
-}
\ No newline at end of file
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/filesystem/TimeProvider.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/filesystem/TimeProvider.java
index 2cb1ac9..6f3045d 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/filesystem/TimeProvider.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/filesystem/TimeProvider.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.vab.modelprovider.filesystem;
 
 import java.time.LocalDateTime;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/filesystem/filesystem/File.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/filesystem/filesystem/File.java
index 20792f9..828832d 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/filesystem/filesystem/File.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/filesystem/filesystem/File.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.vab.modelprovider.filesystem.filesystem;
 
 /**
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/filesystem/filesystem/FileSystem.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/filesystem/filesystem/FileSystem.java
index 880795f..0fe54b1 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/filesystem/filesystem/FileSystem.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/filesystem/filesystem/FileSystem.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.vab.modelprovider.filesystem.filesystem;
 
 import java.io.IOException;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/filesystem/filesystem/FileType.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/filesystem/filesystem/FileType.java
index 395b3c0..635ce2b 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/filesystem/filesystem/FileType.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/filesystem/filesystem/FileType.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.vab.modelprovider.filesystem.filesystem;
 
 /**
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/filesystem/filesystem/GenericFileSystem.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/filesystem/filesystem/GenericFileSystem.java
index 62ad620..772e3c2 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/filesystem/filesystem/GenericFileSystem.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/filesystem/filesystem/GenericFileSystem.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.vab.modelprovider.filesystem.filesystem;
 
 import java.io.FileWriter;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/generic/IVABElementHandler.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/generic/IVABElementHandler.java
index 34a885d..01a2273 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/generic/IVABElementHandler.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/generic/IVABElementHandler.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.vab.modelprovider.generic;
 
 import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/generic/VABModelProvider.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/generic/VABModelProvider.java
index 03f1c9e..f1dc60b 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/generic/VABModelProvider.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/generic/VABModelProvider.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.vab.modelprovider.generic;
 
 import java.util.function.Function;
@@ -30,13 +39,13 @@
 	}
 
 	@Override
-	public Object getModelPropertyValue(String path) {
+	public Object getValue(String path) {
 		Object element = getTargetElement(path);
 		return handler.postprocessObject(element);
 	}
 
 	@Override
-	public void setModelPropertyValue(String path, Object newValue) {
+	public void setValue(String path, Object newValue) {
 		VABPathTools.checkPathForNull(path);
 		if (VABPathTools.isEmptyPath(path)) {
 			// Empty path => parent element == null => replace root, if it exists
@@ -99,7 +108,10 @@
 	@SuppressWarnings("unchecked")
 	@Override
 	public Object invokeOperation(String path, Object... parameters) {
-		Object childElement = getModelPropertyValue(path);
+		
+		path = VABPathTools.stripInvokeFromPath(path);
+		
+		Object childElement = getValue(path);
 
 		// Invoke operation for function interfaces
 		if (childElement instanceof Function<?, ?>) {
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/lambda/VABLambdaHandler.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/lambda/VABLambdaHandler.java
index 27cc661..815783a 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/lambda/VABLambdaHandler.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/lambda/VABLambdaHandler.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.vab.modelprovider.lambda;
 
 import java.util.ArrayList;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/lambda/VABLambdaProvider.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/lambda/VABLambdaProvider.java
index a5b3649..0e67bc8 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/lambda/VABLambdaProvider.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/lambda/VABLambdaProvider.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.vab.modelprovider.lambda;
 
 import java.util.Map;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/lambda/VABLambdaProviderHelper.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/lambda/VABLambdaProviderHelper.java
index 74e75ce..b2a95b9 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/lambda/VABLambdaProviderHelper.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/lambda/VABLambdaProviderHelper.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.vab.modelprovider.lambda;
 
 import java.util.HashMap;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/map/VABMapHandler.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/map/VABMapHandler.java
index f46ffc0..1da707c 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/map/VABMapHandler.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/map/VABMapHandler.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.vab.modelprovider.map;
 
 import java.util.Collection;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/map/VABMapProvider.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/map/VABMapProvider.java
index 3922309..1a90239 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/map/VABMapProvider.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/modelprovider/map/VABMapProvider.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.vab.modelprovider.map;
 
 import java.util.Map;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/api/ConnectorFactory.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/api/ConnectorFactory.java
new file mode 100644
index 0000000..11b7db5
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/api/ConnectorFactory.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.vab.protocol.api;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
+
+/**
+ * ConnectorProvider that caches connectors for addresses to save resources
+ * 
+ * @author schnicke
+ *
+ */
+public abstract class ConnectorFactory implements IConnectorFactory {
+
+	private Map<String, IModelProvider> providerMap = new HashMap<>();
+
+	@Override
+	public IModelProvider getConnector(String addr) {
+		if (!providerMap.containsKey(addr)) {
+			providerMap.put(addr, createProvider(addr));
+		}
+		return providerMap.get(addr);
+	}
+
+	/**
+	 * Creates a new provider for the given address
+	 * 
+	 * @param addr
+	 * @return
+	 */
+	protected abstract IModelProvider createProvider(String addr);
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/api/ConnectorProvider.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/api/ConnectorProvider.java
deleted file mode 100644
index 769e788..0000000
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/api/ConnectorProvider.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package org.eclipse.basyx.vab.protocol.api;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
-
-/**
- * ConnectorProvider that caches connectors for addresses to save resources
- * 
- * @author schnicke
- *
- */
-public abstract class ConnectorProvider implements IConnectorProvider {
-
-	private Map<String, IModelProvider> providerMap = new HashMap<>();
-
-	@Override
-	public IModelProvider getConnector(String addr) {
-		if (!providerMap.containsKey(addr)) {
-			providerMap.put(addr, createProvider(addr));
-		}
-		return providerMap.get(addr);
-	}
-
-	/**
-	 * Creates a new provider for the given address
-	 * 
-	 * @param addr
-	 * @return
-	 */
-	protected abstract IModelProvider createProvider(String addr);
-}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/api/IBaSyxConnector.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/api/IBaSyxConnector.java
index 1d1f9fb..f4582bf 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/api/IBaSyxConnector.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/api/IBaSyxConnector.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.vab.protocol.api;
 
 import org.eclipse.basyx.vab.exception.provider.ProviderException;
@@ -19,7 +28,7 @@
 	 * @return Property value. Object type is assumed to be [Integer | ... |
 	 *         Collection]
 	 */
-	public String getModelPropertyValue(String path) throws ProviderException;
+	public String getValue(String path) throws ProviderException;
 
 	/**
 	 * Sets or overrides existing property, operation or event.
@@ -29,7 +38,7 @@
 	 * @param newValue
 	 *            Updated value
 	 */
-	public String setModelPropertyValue(String path, String newValue) throws ProviderException;
+	public String setValue(String path, String newValue) throws ProviderException;
 
 	/**
 	 * Create a new property, operation, event submodel or aas under the given path
@@ -67,4 +76,11 @@
 	 * @return Return value
 	 */
 	public String invokeOperation(String path, String jsonObject) throws ProviderException;
+	
+	/**
+	 * Get string representation of endpoint for given path for debugging. 
+	 * @param path Requested path
+	 * @return String representing requested endpoint
+	 */
+	public String getEndpointRepresentation(String path);
 }
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/api/IConnectorFactory.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/api/IConnectorFactory.java
new file mode 100644
index 0000000..b0065e8
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/api/IConnectorFactory.java
@@ -0,0 +1,29 @@
+/**
+ * 
+ */
+package org.eclipse.basyx.vab.protocol.api;
+
+import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
+
+/**
+ * Base interface for factories that return IModelProviders that connects to
+ * specific addresses
+ * 
+ * @author schnicke
+ *
+ */
+public interface IConnectorFactory {
+
+	/**
+	 * Gets an IModelProvider connecting the specific address.
+	 *
+	 * @param addr 
+	 * 		The address for which a provider is returned. Must be an address limited to one included endpoint.
+	 * 		For example, it does NOT support basyx://localhost:6998//http://localhost/a/b/c, but http://localhost/a/b/c
+	 * @return
+	 * 		A provider that directly points to the element referenced by the given address. 
+	 * 		E.g. the returned model provider for http://localhost/a/b/c directly points to the element c. Therefore, 
+	 * 		getConnector("http://localhost/a/b/c").getModelPropertyValue(""); returns the value of the element c.  
+	 */
+	public IModelProvider getConnector(String addr);
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/api/IConnectorProvider.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/api/IConnectorProvider.java
deleted file mode 100644
index 9d1f49d..0000000
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/api/IConnectorProvider.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/**
- * 
- */
-package org.eclipse.basyx.vab.protocol.api;
-
-import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
-
-/**
- * Base interface for providers that return IModelProviders that connects to
- * specific addresses
- * 
- * @author schnicke
- *
- */
-public interface IConnectorProvider {
-
-	/**
-	 * Gets an IModelProvider connecting the specific address.
-	 *
-	 * @param addr 
-	 * 		The address for which a provider is returned. Must be an address limited to one included endpoint.
-	 * 		For example, it does NOT support basyx://localhost:6998//http://localhost/a/b/c, but http://localhost/a/b/c
-	 * @return
-	 * 		A provider that directly points to the element referenced by the given address. 
-	 * 		E.g. the returned model provider for http://localhost/a/b/c directly points to the element c. Therefore, 
-	 * 		getConnector("http://localhost/a/b/c").getModelPropertyValue(""); returns the value of the element c.  
-	 */
-	public IModelProvider getConnector(String addr);
-}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/basyx/CoderTools.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/basyx/CoderTools.java
index 92f676d..100c304 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/basyx/CoderTools.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/basyx/CoderTools.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.vab.protocol.basyx;
 
 import java.nio.charset.StandardCharsets;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/basyx/connector/BaSyxConnector.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/basyx/connector/BaSyxConnector.java
index bb0f851..0d0dbc7 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/basyx/connector/BaSyxConnector.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/basyx/connector/BaSyxConnector.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.vab.protocol.basyx.connector;
 
 import java.io.IOException;
@@ -143,7 +152,7 @@
 	 * Invoke a BaSys get operation via HTTP
 	 */
 	@Override
-	public String getModelPropertyValue(String servicePath) {
+	public String getValue(String servicePath) {
 
 		byte[] call = createCall(servicePath, VABBaSyxTCPInterface.BASYX_GET);
 
@@ -160,7 +169,7 @@
 	 *             that carries the Exceptions thrown on the server
 	 */
 	@Override
-	public String setModelPropertyValue(String servicePath, String newValue) {
+	public String setValue(String servicePath, String newValue) {
 
 		byte[] call = createCall(servicePath, newValue, VABBaSyxTCPInterface.BASYX_SET);
 
@@ -278,4 +287,14 @@
 
 		return call;
 	}
+
+	/**
+	 * Get string representation of endpoint for given path for debugging. 
+	 * @param path Requested path
+	 * @return String representing requested endpoint
+	 */
+	@Override
+	public String getEndpointRepresentation(String path) {
+		return "basyx://" + serverSocketAddress.getHostString() + ":" + serverSocketAddress.getPort() + "/" + path;
+	}
 }
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/basyx/connector/BaSyxConnectorFactory.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/basyx/connector/BaSyxConnectorFactory.java
new file mode 100644
index 0000000..0b9846c
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/basyx/connector/BaSyxConnectorFactory.java
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.vab.protocol.basyx.connector;
+
+import org.eclipse.basyx.vab.coder.json.connector.JSONConnector;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+import org.eclipse.basyx.vab.modelprovider.VABPathTools;
+import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
+import org.eclipse.basyx.vab.protocol.api.ConnectorFactory;
+
+
+/**
+ * A connector provider for TCP/BaSyx protocol
+ * 
+ * @author schnicke, kuhn
+ *
+ */
+public class BaSyxConnectorFactory extends ConnectorFactory {
+
+	
+	/**
+	 * Create the provider
+	 */
+	@Override
+	protected IModelProvider createProvider(String address) {
+		// Create address
+		address = VABPathTools.getFirstEndpoint(address);
+		address = address.replaceFirst("basyx://", "");
+		String hostName = address.substring(0, address.indexOf(':'));
+		String[] splitted = address.split("/");
+		int hostPort = Integer.parseInt(splitted[0].substring(address.indexOf(':') + 1));
+
+		// Create connector, connect
+		IModelProvider provider = new JSONConnector(new BaSyxConnector(hostName, hostPort));
+		
+		// Create a proxy, if necessary
+		String path = address.replaceFirst(hostName + ":" + hostPort, "");
+		if (!path.isEmpty() && !path.equals("/")) {
+			provider = new VABElementProxy(path, provider);
+		}
+
+		return provider;
+	}
+
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/basyx/connector/BaSyxConnectorProvider.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/basyx/connector/BaSyxConnectorProvider.java
deleted file mode 100644
index 81476ad..0000000
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/basyx/connector/BaSyxConnectorProvider.java
+++ /dev/null
@@ -1,43 +0,0 @@
-package org.eclipse.basyx.vab.protocol.basyx.connector;
-
-import org.eclipse.basyx.vab.coder.json.connector.JSONConnector;
-import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
-import org.eclipse.basyx.vab.modelprovider.VABPathTools;
-import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
-import org.eclipse.basyx.vab.protocol.api.ConnectorProvider;
-
-
-/**
- * A connector provider for TCP/BaSyx protocol
- * 
- * @author schnicke, kuhn
- *
- */
-public class BaSyxConnectorProvider extends ConnectorProvider {
-
-	
-	/**
-	 * Create the provider
-	 */
-	@Override
-	protected IModelProvider createProvider(String address) {
-		// Create address
-		address = VABPathTools.getFirstEndpoint(address);
-		address = address.replace("basyx://", "");
-		String hostName = address.substring(0, address.indexOf(':'));
-		String[] splitted = address.split("/");
-		int hostPort = Integer.parseInt(splitted[0].substring(address.indexOf(':') + 1));
-
-		// Create connector, connect
-		IModelProvider provider = new JSONConnector(new BaSyxConnector(hostName, hostPort));
-		
-		// Create a proxy, if necessary
-		String path = address.replace(hostName + ":" + hostPort, "");
-		if (!path.isEmpty() && !path.equals("/")) {
-			provider = new VABElementProxy(path, provider);
-		}
-
-		return provider;
-	}
-
-}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/basyx/server/BaSyxTCPServer.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/basyx/server/BaSyxTCPServer.java
index 2ee4d10..4af9d10 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/basyx/server/BaSyxTCPServer.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/basyx/server/BaSyxTCPServer.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.vab.protocol.basyx.server;
 
 import java.io.IOException;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/basyx/server/VABBaSyxTCPInterface.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/basyx/server/VABBaSyxTCPInterface.java
index a33e8da..b67c0b0 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/basyx/server/VABBaSyxTCPInterface.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/basyx/server/VABBaSyxTCPInterface.java
@@ -1,8 +1,16 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.vab.protocol.basyx.server;
 
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
-import java.io.PrintWriter;
 import java.nio.ByteBuffer;
 import java.nio.channels.ClosedChannelException;
 import java.nio.channels.SocketChannel;
@@ -81,8 +89,7 @@
 	 */
 	public void processInputFrame(byte[] rxFrame) throws IOException {
 		// Create output streams
-		ByteArrayOutputStream byteArrayOutput = new ByteArrayOutputStream();
-		PrintWriter output = new PrintWriter(byteArrayOutput);
+		ByteArrayOutputStream output = new ByteArrayOutputStream();
 
 		// Get command
 		switch (rxFrame[0]) {
@@ -107,7 +114,7 @@
 
 			// Send response frame
 			output.flush();
-			sendResponseFrame(byteArrayOutput);
+			sendResponseFrame(output);
 
 			break;
 		}
@@ -133,7 +140,7 @@
 
 			// Send response frame
 			output.flush();
-			sendResponseFrame(byteArrayOutput);
+			sendResponseFrame(output);
 
 			break;
 		}
@@ -159,7 +166,7 @@
 
 			// Send response frame
 			output.flush();
-			sendResponseFrame(byteArrayOutput);
+			sendResponseFrame(output);
 
 			break;
 		}
@@ -194,7 +201,7 @@
 
 			// Send response frame
 			output.flush();
-			sendResponseFrame(byteArrayOutput);
+			sendResponseFrame(output);
 
 			break;
 		}
@@ -219,7 +226,7 @@
 
 			// Send response frame
 			output.flush();
-			sendResponseFrame(byteArrayOutput);
+			sendResponseFrame(output);
 
 			break;
 		}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/http/connector/HTTPConnector.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/http/connector/HTTPConnector.java
index 87cf852..83f39cf 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/http/connector/HTTPConnector.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/http/connector/HTTPConnector.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.vab.protocol.http.connector;
 
 import javax.ws.rs.client.Client;
@@ -7,14 +16,18 @@
 import javax.ws.rs.client.WebTarget;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
 
 import org.eclipse.basyx.vab.exception.provider.ProviderException;
 import org.eclipse.basyx.vab.modelprovider.VABPathTools;
 import org.eclipse.basyx.vab.protocol.api.IBaSyxConnector;
+import org.eclipse.basyx.vab.protocol.http.server.ExceptionToHTTPCodeMapper;
 import org.glassfish.jersey.client.HttpUrlConnectorProvider;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import io.netty.handler.codec.http.HttpMethod;
+
 /**
  * HTTP connector class
  * 
@@ -27,7 +40,7 @@
 	
 	private String address;
 	private String mediaType;
-	private Client client;
+	protected Client client;
 
 	/**
 	 * Invoke a BaSys get operation via HTTP GET
@@ -39,12 +52,12 @@
 	 * @return the requested object
 	 */
 	@Override
-	public String getModelPropertyValue(String servicePath) {
+	public String getValue(String servicePath) {
 		return httpGet(servicePath);
 	}
 
 	public HTTPConnector(String address) {
-		this(address, MediaType.APPLICATION_JSON);
+		this(address, MediaType.APPLICATION_JSON + ";charset=UTF-8");
 	}
 
 	public HTTPConnector(String address, String mediaType) {
@@ -69,7 +82,7 @@
 	 *            should be an IElement of type Property, Operation or Event
 	 */
 	@Override
-	public String setModelPropertyValue(String servicePath, String newValue) throws ProviderException {
+	public String setValue(String servicePath, String newValue) throws ProviderException {
 
 		return httpPut(servicePath, newValue);
 	}
@@ -125,7 +138,6 @@
 		// Build request, set JSON encoding
 		Builder request = resource.request();
 		request.accept(mediaType);
-
 		// Return JSON request
 		return request;
 	}
@@ -159,7 +171,14 @@
 		Builder request = retrieveBuilder(servicePath);
 
 		// Perform request
-		Response rsp = request.get();
+		Response rsp = null;
+		try {
+			rsp = request.get();
+		} finally {
+			if (!isRequestSuccess(rsp)) {
+				throw this.handleProcessingException(HttpMethod.GET, getStatusCode(rsp));	
+			}
+		}
 
 		// Return response message (header)
 		return rsp.readEntity(String.class);
@@ -171,7 +190,14 @@
 		Builder request = retrieveBuilder(servicePath);
 
 		// Perform request
-		Response rsp = request.put(Entity.entity(newValue, mediaType));
+		Response rsp = null;
+		try {
+			rsp = request.put(Entity.entity(newValue, mediaType));
+		} finally {
+			if (!isRequestSuccess(rsp)) {
+				throw this.handleProcessingException(HttpMethod.PUT, getStatusCode(rsp));	
+			}
+		}
 
 		// Return response message (header)
 		return rsp.readEntity(String.class);
@@ -181,11 +207,15 @@
 	private String httpPatch(String servicePath, String newValue) throws ProviderException {
 		logger.trace("[HTTP Patch] {} {}", VABPathTools.concatenatePaths(address, servicePath), newValue);
 
-		// Invoke service call via web services
-		Client client = ClientBuilder.newClient();
-
 		// Create and invoke HTTP PATCH request
-		Response rsp = client.target(VABPathTools.concatenatePaths(address, servicePath)).request().build("PATCH", Entity.text(newValue)).property(HttpUrlConnectorProvider.SET_METHOD_WORKAROUND, true).invoke();
+		Response rsp = null;
+		try {
+			rsp = this.client.target(VABPathTools.concatenatePaths(address, servicePath)).request().build("PATCH", Entity.text(newValue)).property(HttpUrlConnectorProvider.SET_METHOD_WORKAROUND, true).invoke();
+		} finally {
+			if (!isRequestSuccess(rsp)) {
+				throw this.handleProcessingException(HttpMethod.PATCH, getStatusCode(rsp));	
+			}
+		}
 
 		// Return response message (header)
 		return rsp.readEntity(String.class);
@@ -197,7 +227,14 @@
 		Builder request = retrieveBuilder(servicePath);
 
 		// Perform request
-		Response rsp = request.post(Entity.entity(parameter, mediaType));
+		Response rsp = null;
+		try {
+			rsp = request.post(Entity.entity(parameter, mediaType));
+		} finally {
+			if (!isRequestSuccess(rsp)) {
+				throw this.handleProcessingException(HttpMethod.POST, getStatusCode(rsp));	
+			}
+		}
 
 		// Return response message (header)
 		return rsp.readEntity(String.class);
@@ -209,7 +246,14 @@
 		Builder request = retrieveBuilder(servicePath);
 
 		// Perform request
-		Response rsp = request.delete();
+		Response rsp = null;
+		try {
+			rsp = request.delete();
+		} finally {
+			if (!isRequestSuccess(rsp)) {
+				throw this.handleProcessingException(HttpMethod.DELETE, getStatusCode(rsp));	
+			}
+		}
 
 		// Return response message (header)
 		return rsp.readEntity(String.class);
@@ -231,4 +275,35 @@
 		return buildRequest(client, VABPathTools.concatenatePaths(address, servicePath));
 	}
 
+	private ProviderException handleProcessingException(HttpMethod method, int statusCode) {
+		return ExceptionToHTTPCodeMapper.mapToException(statusCode, "[HTTP " + method.name() + "] Failed to request " + this.address + " with mediatype " + this.mediaType);
+	}
+	
+	/**
+	 * Get status code from HTTP Response
+	 * @param rsp
+	 * @return
+	 */
+	private int getStatusCode(Response rsp) {
+		return rsp != null ? rsp.getStatus() : 0;
+	}
+	
+	/**
+	 * Returns true if the response is succeeded
+	 * @param rsp
+	 * @return
+	 */
+	private boolean isRequestSuccess(Response rsp) {
+		return rsp != null && rsp.getStatusInfo().getFamily() == Status.Family.SUCCESSFUL;
+	}
+
+	/**
+	 * Get string representation of endpoint for given path for debugging. 
+	 * @param path Requested path
+	 * @return String representing requested endpoint
+	 */
+	@Override
+	public String getEndpointRepresentation(String path) {
+		return VABPathTools.concatenatePaths(address, path);
+	}
 }
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/http/connector/HTTPConnectorFactory.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/http/connector/HTTPConnectorFactory.java
new file mode 100644
index 0000000..38971ee
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/http/connector/HTTPConnectorFactory.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.vab.protocol.http.connector;
+
+import org.eclipse.basyx.vab.coder.json.connector.JSONConnector;
+import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
+import org.eclipse.basyx.vab.protocol.api.ConnectorFactory;
+
+public class HTTPConnectorFactory extends ConnectorFactory {
+
+	/**
+	 * returns HTTPConnetor wrapped with ConnectedHashmapProvider that handles
+	 * message header information
+	 */
+	@Override
+	protected IModelProvider createProvider(String addr) {
+
+		return new JSONConnector(new HTTPConnector(addr));
+	}
+
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/http/connector/HTTPConnectorProvider.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/http/connector/HTTPConnectorProvider.java
deleted file mode 100644
index fb86647..0000000
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/http/connector/HTTPConnectorProvider.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package org.eclipse.basyx.vab.protocol.http.connector;
-
-import org.eclipse.basyx.vab.coder.json.connector.JSONConnector;
-import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
-import org.eclipse.basyx.vab.protocol.api.ConnectorProvider;
-
-public class HTTPConnectorProvider extends ConnectorProvider {
-
-	/**
-	 * returns HTTPConnetor wrapped with ConnectedHashmapProvider that handles
-	 * message header information
-	 */
-	@Override
-	protected IModelProvider createProvider(String addr) {
-
-		return new JSONConnector(new HTTPConnector(addr));
-	}
-
-}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/http/server/AASHTTPServer.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/http/server/AASHTTPServer.java
deleted file mode 100644
index 712de52..0000000
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/http/server/AASHTTPServer.java
+++ /dev/null
@@ -1,130 +0,0 @@
-package org.eclipse.basyx.vab.protocol.http.server;
-
-import java.io.File;
-import java.util.Iterator;
-import java.util.Map.Entry;
-
-import javax.servlet.http.HttpServlet;
-
-import org.apache.catalina.Context;
-import org.apache.catalina.LifecycleEvent;
-import org.apache.catalina.LifecycleException;
-import org.apache.catalina.LifecycleListener;
-import org.apache.catalina.LifecycleState;
-import org.apache.catalina.startup.Tomcat;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Starter Class for Apache Tomcat 8.0.53 HTTP server that adds the provided servlets and respective mappings on startup.
- * 
- * @author pschorn, espen
- * 
- */
-public class AASHTTPServer {
-	
-	private static Logger logger = LoggerFactory.getLogger(AASHTTPServer.class);
-	
-	private Tomcat tomcat;
-
-	static {
-		// Enable coding of forward slash in tomcat
-		System.setProperty("org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH", "true");
-	}
-	   
-	/**
-	 * Constructor
-	 * 
-	 * Create new Tomcat instance and add the provided servlet mappings
-	 * 
-	 * @param context
-	 *            Basyx context with of url mappings to HTTPServlet
-	 */
-	public AASHTTPServer(BaSyxContext context) {
-		// Instantiate and setup Tomcat server
-		tomcat = new Tomcat();
-		tomcat.setPort(context.port);
-		tomcat.setHostname(context.hostname);
-		tomcat.getHost().setAppBase(".");
-
-		// Create servlet context
-		// - Base path for resource files
-		File docBase = new File(context.docBasePath); // System.getProperty("java.io.tmpdir"));
-		// - Create context for servlets
-		Context rootCtx = tomcat.addContext(context.contextPath, docBase.getAbsolutePath());
-
-		// Iterate all servlets in context
-		Iterator<Entry<String, HttpServlet>> it = context.entrySet().iterator();
-		while (it.hasNext()) {
-			// Servlet entry
-			Entry<String, HttpServlet> entry = it.next();
-
-			// Servlet mapping
-			String mapping = entry.getKey();
-			HttpServlet servlet = entry.getValue();
-
-			// Add new Servlet and Mapping to tomcat environment
-			Tomcat.addServlet(rootCtx, Integer.toString(servlet.hashCode()), servlet);
-			rootCtx.addServletMappingDecoded(mapping, Integer.toString(servlet.hashCode()));
-		}
-	}
-	
-	/**
-	 * Starts the server in a new thread to avoid blocking the main thread
-	 */
-	public void start() {
-		logger.trace("Starting Tomcat.....");
-        
-		Thread serverThread = new Thread(() -> {
-			try {
-				tomcat.stop();
-
-				// Adds listener that notifies the tomcat object when the server has started
-				tomcat.getServer().addLifecycleListener(new LifecycleListener() {
-					@Override
-					public void lifecycleEvent(LifecycleEvent event) {
-						if (event.getLifecycle().getState() == LifecycleState.STARTED) {
-							synchronized (tomcat) {
-								tomcat.notifyAll();
-							}
-						}
-					}
-				});
-
-				tomcat.start();
-				
-				// Keeps the server thread alive until the server is shut down
-				tomcat.getServer().await();
-			} catch (LifecycleException e) {
-				logger.error("Exception in start", e);
-			}
-		});
-		serverThread.start();
-
-		synchronized (tomcat) {
-			try {
-				tomcat.wait();
-			} catch (InterruptedException e) {
-				logger.error("Exception in start", e);
-			}
-		}
-	}
-	
-	/**
-	 * This Method stops and destroys the tomcat instance. This is important since Tomcat would be already 
-	 * bound to port 8080 when new tests are run that require a start of tomcat
-	 */
-	public void shutdown() {
-		logger.trace("Shutting down BaSyx HTTP Server...");
-		
-		try {
-			tomcat.stop();
-			tomcat.destroy();
-		} catch (LifecycleException e) {
-			// TODO Auto-generated catch block
-			logger.error("Exception in shutdown", e);
-		}
-	}
-	
-	
-}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/http/server/BaSyxContext.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/http/server/BaSyxContext.java
index 387f3ce..9b77690 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/http/server/BaSyxContext.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/http/server/BaSyxContext.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.vab.protocol.http.server;
 
 import java.util.HashMap;
@@ -10,7 +19,7 @@
 /**
  * BaSyx context that contains an Industrie 4.0 Servlet infrastructure 
  * 
- * @author kuhn
+ * @author kuhn, haque
  *
  */
 public class BaSyxContext extends HashMap<String, HttpServlet> {
@@ -43,6 +52,20 @@
 	 */
 	protected int port;
 	
+	/**
+	 * Indicates whether the connection is secures or not
+	 */
+	private boolean isSecuredConnection;
+	
+	/**
+	 * Password of the SSL key
+	 */
+	private String keyPassword;
+	
+	/**
+	 * Path to the certificate
+	 */
+	private String certificatePath;
 	
 	/**
 	 * Servlet parameter
@@ -62,7 +85,11 @@
 
 	
 	/**
-	 * Constructor
+	 * Initiates a BasyxContext
+	 * @param reqContextPath context path
+	 * @param reqDocBasePath  base path of doc
+	 * @param hostn host name
+	 * @param reqPort connection port
 	 */
 	public BaSyxContext(String reqContextPath, String reqDocBasePath, String hostn, int reqPort) {
 		// Store context path and doc base path
@@ -70,8 +97,26 @@
 		docBasePath = reqDocBasePath;
 		hostname = hostn;
 		port        = reqPort;
+		isSecuredConnection = false;
 	}
 	
+	/**
+	 * Initiates a BasyxContext. this constructor can indicate whether 
+	 * the connection is secured or not
+	 * @param reqContextPath context path
+	 * @param reqDocBasePath  base path of doc
+	 * @param hostn host name
+	 * @param reqPort connection port
+	 * @param isSecuredCon boolean value indicating the connection is secured or not
+	 * @param keyPass password of the SSL key
+	 * @param keyPath path to the SSL certificate
+	 */
+	public BaSyxContext(String reqContextPath, String reqDocBasePath, String hostn, int reqPort, boolean isSecuredCon, String keyPath,  String keyPass) {
+		this(reqContextPath, reqDocBasePath, hostn, reqPort);
+		this.isSecuredConnection = isSecuredCon;
+		this.certificatePath = keyPath;
+		this.keyPassword = keyPass;
+	}
 	
 	
 	/**
@@ -131,5 +176,48 @@
 	public int getPort() {
 		return port;
 	}
+	
+	/**
+	 * Returns whether the secured connection enabled or not
+	 * @return
+	 */
+	public boolean isSecuredConnectionEnabled() {
+		return this.isSecuredConnection;
+	}
+
+	/**
+	 * Returns password of the SSL key
+	 * @return
+	 */
+	public String getKeyPassword() {
+		return keyPassword;
+	}
+
+
+	/**
+	 * Sets password of the SSL key
+	 * @param keyPassword
+	 */
+	public void setKeyPassword(String keyPassword) {
+		this.keyPassword = keyPassword;
+	}
+
+
+	/**
+	 * Returns Path to the certificate
+	 * @return
+	 */
+	public String getCertificatePath() {
+		return certificatePath;
+	}
+
+
+	/**
+	 * Sets Certificate Path
+	 * @param certificatePath
+	 */
+	public void setCertificatePath(String certificatePath) {
+		this.certificatePath = certificatePath;
+	}
 }
 
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/http/server/BaSyxHTTPServer.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/http/server/BaSyxHTTPServer.java
new file mode 100644
index 0000000..a5eb5cc
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/http/server/BaSyxHTTPServer.java
@@ -0,0 +1,175 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.vab.protocol.http.server;
+
+import java.io.File;
+import java.util.Iterator;
+import java.util.Map.Entry;
+import java.util.UUID;
+
+import javax.servlet.http.HttpServlet;
+
+import org.apache.catalina.Context;
+import org.apache.catalina.LifecycleEvent;
+import org.apache.catalina.LifecycleException;
+import org.apache.catalina.LifecycleListener;
+import org.apache.catalina.LifecycleState;
+import org.apache.catalina.connector.Connector;
+import org.apache.catalina.startup.Tomcat;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Starter Class for Apache Tomcat 8.0.53 HTTP server that adds the provided servlets and respective mappings on startup.
+ * 
+ * @author pschorn, espen, haque
+ * 
+ */
+public class BaSyxHTTPServer {
+	
+	private static Logger logger = LoggerFactory.getLogger(BaSyxHTTPServer.class);
+	
+	private Tomcat tomcat;
+
+	static {
+		// Enable coding of forward slash in tomcat
+		System.setProperty("org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH", "true");
+	}
+	   
+	/**
+	 * Constructor
+	 * 
+	 * Create new Tomcat instance and add the provided servlet mappings
+	 * 
+	 * @param context
+	 *            Basyx context with of url mappings to HTTPServlet
+	 */
+
+	public BaSyxHTTPServer(BaSyxContext context) {
+		// Instantiate and setup Tomcat server
+		tomcat = new Tomcat();
+
+		// Set random name to prevent lifecycle expections during shutdown of multiple
+		// instances
+		tomcat.getEngine().setName(UUID.randomUUID().toString());
+		
+		if (context.isSecuredConnectionEnabled()) {
+			Connector httpsConnector = tomcat.getConnector();
+			configureSslConnector(context, httpsConnector);
+		} else {
+			tomcat.setPort(context.port);
+		}
+		
+		tomcat.setHostname(context.hostname);
+		tomcat.getHost().setAppBase(".");
+
+		// Create servlet context
+		// - Base path for resource files
+		File docBase = new File(context.docBasePath); // System.getProperty("java.io.tmpdir"));
+		// - Create context for servlets
+		Context rootCtx = tomcat.addContext(context.contextPath, docBase.getAbsolutePath());
+
+		// Iterate all servlets in context
+		Iterator<Entry<String, HttpServlet>> it = context.entrySet().iterator();
+		while (it.hasNext()) {
+			// Servlet entry
+			Entry<String, HttpServlet> entry = it.next();
+
+			// Servlet mapping
+			String mapping = entry.getKey();
+			HttpServlet servlet = entry.getValue();
+
+			// Add new Servlet and Mapping to tomcat environment
+			Tomcat.addServlet(rootCtx, Integer.toString(servlet.hashCode()), servlet);
+			rootCtx.addServletMappingDecoded(mapping, Integer.toString(servlet.hashCode()));
+		}
+	}
+	
+	/**
+	 * SSL Configuration for SSL connector
+	 * @param context
+	 * @param httpsConnector
+	 */
+	private void configureSslConnector(BaSyxContext context, Connector httpsConnector) {
+		httpsConnector.setPort(context.port);
+		httpsConnector.setSecure(true);
+		httpsConnector.setScheme("https");
+		httpsConnector.setAttribute("keystoreFile", context.getCertificatePath());
+		httpsConnector.setAttribute("clientAuth", "false");
+		httpsConnector.setAttribute("sslProtocol", "TLS");
+		httpsConnector.setAttribute("SSLEnabled", true);
+		httpsConnector.setAttribute("protocol", "HTTP/1.1");
+		httpsConnector.setAttribute("keystorePass", context.getKeyPassword());
+		
+		httpsConnector.setAttribute("keyAlias", "tomcat");
+		
+		httpsConnector.setAttribute("maxThreads", "200");
+		httpsConnector.setAttribute("protocol", "org.apache.coyote.http11.Http11AprProtocol");
+	 }
+	
+	/**
+	 * Starts the server in a new thread to avoid blocking the main thread
+	 */
+	public void start() {
+		logger.trace("Starting Tomcat.....");
+        
+		Thread serverThread = new Thread(() -> {
+			try {
+				tomcat.stop();
+
+				// Adds listener that notifies the tomcat object when the server has started
+				tomcat.getServer().addLifecycleListener(new LifecycleListener() {
+					@Override
+					public void lifecycleEvent(LifecycleEvent event) {
+						if (event.getLifecycle().getState() == LifecycleState.STARTED) {
+							synchronized (tomcat) {
+								tomcat.notifyAll();
+							}
+						}
+					}
+				});
+
+				tomcat.start();
+				
+				// Keeps the server thread alive until the server is shut down
+				tomcat.getServer().await();
+			} catch (LifecycleException e) {
+				logger.error("Exception in start", e);
+			}
+		});
+		serverThread.start();
+
+		synchronized (tomcat) {
+			try {
+				tomcat.wait();
+			} catch (InterruptedException e) {
+				logger.error("Exception in start", e);
+			}
+		}
+	}
+	
+	/**
+	 * This Method stops and destroys the tomcat instance. This is important since Tomcat would be already 
+	 * bound to port 8080 when new tests are run that require a start of tomcat
+	 */
+	public void shutdown() {
+		logger.trace("Shutting down BaSyx HTTP Server...");
+		
+		try {
+			tomcat.stop();
+			tomcat.destroy();
+		} catch (LifecycleException e) {
+			// TODO Auto-generated catch block
+			logger.error("Exception in shutdown", e);
+		}
+	}
+	
+	
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/http/server/BasysHTTPServlet.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/http/server/BasysHTTPServlet.java
index 92d3a90..be0af71 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/http/server/BasysHTTPServlet.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/http/server/BasysHTTPServlet.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.vab.protocol.http.server;
 
 import java.io.IOException;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/http/server/ExceptionToHTTPCodeMapper.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/http/server/ExceptionToHTTPCodeMapper.java
index 4f58027..bcc23ea 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/http/server/ExceptionToHTTPCodeMapper.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/http/server/ExceptionToHTTPCodeMapper.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.vab.protocol.http.server;
 
 import org.eclipse.basyx.vab.exception.provider.MalformedRequestException;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/http/server/VABHTTPInterface.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/http/server/VABHTTPInterface.java
index 692305b..00900ae 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/http/server/VABHTTPInterface.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/http/server/VABHTTPInterface.java
@@ -1,6 +1,16 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.vab.protocol.http.server;
 
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.PrintWriter;
 import java.io.UnsupportedEncodingException;
 import java.util.ArrayList;
@@ -9,7 +19,6 @@
 import java.util.StringJoiner;
 
 import javax.servlet.ServletException;
-import javax.servlet.ServletInputStream;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
@@ -21,6 +30,9 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.base.Charsets;
+import com.google.common.io.ByteSource;
+
 
 /**
  * VAB provider class that enables access to an IModelProvider via HTTP REST
@@ -91,8 +103,6 @@
 	 */
 	@Override
 	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
-		PrintWriter responseWriter = resp.getWriter();
-		
 		try {
 			String path = extractPath(req);
 
@@ -103,12 +113,10 @@
 			resp.setStatus(200);
 
 			// Process get request
-			providerBackend.processBaSysGet(path, responseWriter);
-			responseWriter.flush();
+			providerBackend.processBaSysGet(path, resp.getOutputStream());
 		} catch(ProviderException e) {
 			int httpCode = ExceptionToHTTPCodeMapper.mapFromException(e);
 			resp.setStatus(httpCode);
-			responseWriter.flush();
 			logger.debug("Exception in HTTP-GET. Response-code: " + httpCode, e);
 		}
 		
@@ -120,21 +128,19 @@
 	 */
 	@Override
 	protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
-		PrintWriter responseWriter = resp.getWriter();
-		
 		try {
 			String path = extractPath(req);
 			String serValue = extractSerializedValue(req);
 			logger.trace("DoPut: {}", serValue);
 
+			resp.setContentType("application/json");
+			resp.setCharacterEncoding("UTF-8");
 			resp.setStatus(200);
 
-			providerBackend.processBaSysSet(path, serValue.toString(), responseWriter);
-			responseWriter.flush();
+			providerBackend.processBaSysSet(path, serValue.toString(), resp.getOutputStream());
 		} catch(ProviderException e) {
 			int httpCode = ExceptionToHTTPCodeMapper.mapFromException(e);
 			resp.setStatus(httpCode);
-			responseWriter.flush();
 			logger.debug("Exception in HTTP-PUT. Response-code: " + httpCode, e);
 		}
 	}
@@ -147,8 +153,6 @@
 	 */
 	@Override
 	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
-		PrintWriter responseWriter = resp.getWriter();
-
 		try {
 			String path = extractPath(req);
 			String serValue = extractSerializedValue(req);
@@ -161,21 +165,18 @@
 			resp.setCharacterEncoding("UTF-8");
 
 			// Check if request is for property creation or operation invoke
-			if (VABPathTools.isOperationPath(path)) {
+			if (VABPathTools.isOperationInvokationPath(path)) {
 			// Invoke BaSys VAB 'invoke' primitive
 
-				providerBackend.processBaSysInvoke(path, serValue, responseWriter);
-				responseWriter.flush();
+				providerBackend.processBaSysInvoke(path, serValue, resp.getOutputStream());
 
 			} else {
 			// Invoke the BaSys 'create' primitive
-				providerBackend.processBaSysCreate(path, serValue, responseWriter);
-				responseWriter.flush();
+				providerBackend.processBaSysCreate(path, serValue, resp.getOutputStream());
 			}
 		} catch (ProviderException e) {
 			int httpCode = ExceptionToHTTPCodeMapper.mapFromException(e);
 			resp.setStatus(httpCode);
-			responseWriter.flush();
 			logger.debug("Exception in HTTP-POST. Response-code: " + httpCode, e);
 		}
 	}
@@ -187,7 +188,6 @@
 	 */
 	@Override
 	protected void doPatch(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
-		PrintWriter responseWriter = resp.getWriter();
 		try {
 			String path = extractPath(req);
 			String serValue = extractSerializedValue(req);
@@ -195,12 +195,10 @@
 
 			resp.setStatus(200);
 
-			providerBackend.processBaSysDelete(path, serValue, responseWriter);
-			responseWriter.flush();
+			providerBackend.processBaSysDelete(path, serValue, resp.getOutputStream());
 		} catch(ProviderException e) {
 			int httpCode = ExceptionToHTTPCodeMapper.mapFromException(e);
 			resp.setStatus(httpCode);
-			responseWriter.flush();
 			logger.debug("Exception in HTTP-PATCH. Response-code: " + httpCode, e);
 		}
 	}
@@ -211,8 +209,6 @@
 	 */
 	@Override
 	protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
-		PrintWriter responseWriter = resp.getWriter();
-
 		try {
 			String path = extractPath(req);
 
@@ -222,12 +218,10 @@
 			resp.setStatus(200);
 
 
-			providerBackend.processBaSysDelete(path, nullParam, responseWriter);
-			responseWriter.flush();
+			providerBackend.processBaSysDelete(path, nullParam, resp.getOutputStream());
 		} catch(ProviderException e) {
 			int httpCode = ExceptionToHTTPCodeMapper.mapFromException(e);
 			resp.setStatus(httpCode);
-			responseWriter.flush();
 			logger.debug("Exception in HTTP-DELETE. Response-code: " + httpCode, e);
 		}
 	}
@@ -305,14 +299,14 @@
 	 * @throws IOException
 	 */
 	private String extractSerializedValue(HttpServletRequest req) throws IOException {
-		// Read request body
-		ServletInputStream is = req.getInputStream();		
-		StringBuilder serValue = new StringBuilder();
-
-		// This seems kind of slow...
-		while (!is.isFinished()) {
-			serValue.append(String.valueOf((char) (byte) is.read()));
-		}
-		return serValue.toString();
+		// https://www.baeldung.com/convert-input-stream-to-string#guava
+		ByteSource byteSource = new ByteSource() {
+	        @Override
+	        public InputStream openStream() throws IOException {
+	            return req.getInputStream();
+	        }
+	    };
+	 
+	    return byteSource.asCharSource(Charsets.UTF_8).read();
 	}
 }
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/opcua/connector/OpcUaConnector.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/opcua/connector/OpcUaConnector.java
index 9ce47d3..c315e3f 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/opcua/connector/OpcUaConnector.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/opcua/connector/OpcUaConnector.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.vab.protocol.opcua.connector;
 
 import java.util.ArrayList;
@@ -45,24 +54,25 @@
      * @throws Exception
      */
     @Override
-    public String getModelPropertyValue(String servicePath) {
+    public String getValue(String servicePath) {
         try {
             clientRunner = new BaSyxOpcUaClientRunner(address);
             clientRunner.run();
         } catch (Exception e) {
         	logger.error("Exception in getModelPropertyValue", e);
+        	throw new RuntimeException(e);
         }
         return opcUaRead(translateBrowsePathToNodeId(servicePath)[1]);
     }
 
     @Override
-	public void setModelPropertyValue(String servicePath, Object newValue) throws ProviderException {
+	public void setValue(String servicePath, Object newValue) throws ProviderException {
         try {
             clientRunner = new BaSyxOpcUaClientRunner(address);
             clientRunner.run();
         } catch (Exception e) {
-            // TODO Auto-generated catch block
         	logger.error("Exception in setModelPropertyValue", e);
+        	throw new RuntimeException(e);
         }
         opcUaWrite(translateBrowsePathToNodeId(servicePath)[1], newValue);
     }
@@ -89,6 +99,7 @@
             clientRunner.run();
         } catch (Exception e) {
         	logger.error("Exception in invokeOperation", e);
+        	throw new RuntimeException(e);
         }
         return opcUaMethodCall(translateBrowsePathToNodeId(servicePath), parameters);
     }
@@ -182,20 +193,20 @@
             CompletableFuture<TranslateBrowsePathsToNodeIdsResponse> result_parent = clientRunner
                     .translate(bp_parent_list);
             if (result_node.get().getResults().length == 0) {
-                logger.warn("TranslateBrowsePathsToNodeIdsResponse result size = 0, checkthe browse path!");
+                logger.warn("TranslateBrowsePathsToNodeIdsResponse result size = 0, check the browse path!");
                 return null;
             }
             if (result_node.get().getResults().length > 1) {
             	logger.warn("TranslateBrowsePathsToNodeIdsResponse result size > 1, the method returns only the first one!");
             }
+			if (result_node.get().getResults()[0].getTargets() == null || result_node.get().getResults()[0].getTargets().length == 0) {
+            	logger.warn("TranslateBrowsePathsToNodeIdsResponse targets size = 0, check the browse path!");
+				logger.trace(result_node.get().getResults()[0].getStatusCode().toString());
+				return null;
+            }
             if (result_node.get().getResults()[0].getTargets().length > 1) {
             	logger.warn("TranslateBrowsePathsToNodeIdsResponse targets size > 1, the method returns only the first one!");
             }
-            if (result_node.get().getResults()[0].getTargets().length == 0) {
-            	logger.warn("TranslateBrowsePathsToNodeIdsResponse targets size = 0, check the browse path!");
-                logger.trace(result_node.get().getResults()[0].getStatusCode().toString());
-                return null;
-            }
             Object nodeIdentifier = result_node.get().getResults()[0].getTargets()[0].getTargetId().getIdentifier();
             Object parentIdentifier = result_parent.get().getResults()[0].getTargets()[0].getTargetId().getIdentifier();
             UShort nodeNsIdx = result_node.get().getResults()[0].getTargets()[0].getTargetId().getNamespaceIndex();
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/opcua/connector/OpcUaConnectorProvider.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/opcua/connector/OpcUaConnectorProvider.java
index 450f534..c5c6477 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/opcua/connector/OpcUaConnectorProvider.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/opcua/connector/OpcUaConnectorProvider.java
@@ -1,7 +1,16 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.vab.protocol.opcua.connector;
 
 import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
-import org.eclipse.basyx.vab.protocol.api.ConnectorProvider;
+import org.eclipse.basyx.vab.protocol.api.ConnectorFactory;
 
 /**
  * OPC UA connector provider class
@@ -9,7 +18,7 @@
  * @author kdorofeev
  *
  */
-public class OpcUaConnectorProvider extends ConnectorProvider {
+public class OpcUaConnectorProvider extends ConnectorFactory {
 
 	/**
 	 * returns HTTPConnetor wrapped with ConnectedHashmapProvider that handles
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/opcua/server/BaSyxOpcUaClient.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/opcua/server/BaSyxOpcUaClient.java
index 14aa223..f08a453 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/opcua/server/BaSyxOpcUaClient.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/opcua/server/BaSyxOpcUaClient.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.vab.protocol.opcua.server;
 
 import java.util.concurrent.CompletableFuture;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/opcua/server/BaSyxOpcUaClientRunner.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/opcua/server/BaSyxOpcUaClientRunner.java
index 616df4c..8c38c1f 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/opcua/server/BaSyxOpcUaClientRunner.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/opcua/server/BaSyxOpcUaClientRunner.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.vab.protocol.opcua.server;
 
 import static org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.Unsigned.uint;
@@ -115,7 +124,7 @@
 
                 try {
                     Thread.sleep(1000);
-                    System.exit(0);
+                    throw new RuntimeException("Could not disconnect from server '" + endpointUrl + "'");
                 } catch (InterruptedException e) {
                 	logger.error("Exception in run", e);
                 }
@@ -128,7 +137,7 @@
 
             try {
                 Thread.sleep(1000);
-                System.exit(0);
+                throw new RuntimeException("Could not connect to server '" + endpointUrl + "'");
             } catch (InterruptedException e) {
             	logger.error("Exception in run", e);
             }
@@ -153,4 +162,4 @@
         return client.translateBrowsePaths(browsePaths);
     }
 
-}
\ No newline at end of file
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/opcua/server/KeyStoreLoaderClient.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/opcua/server/KeyStoreLoaderClient.java
index 4c45abd..535c994 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/opcua/server/KeyStoreLoaderClient.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/opcua/server/KeyStoreLoaderClient.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.vab.protocol.opcua.server;
 
 import java.io.InputStream;
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/registry/api/IVABRegistryService.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/registry/api/IVABRegistryService.java
new file mode 100644
index 0000000..dccdfd0
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/registry/api/IVABRegistryService.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.vab.registry.api;
+
+/**
+ * Directory service SDK interface.
+ * 
+ * @author kuhn
+ *
+ */
+public interface IVABRegistryService {
+
+	
+	/**
+	 * Add a mapping to directory
+	 */
+	public IVABRegistryService addMapping(String key, String value);
+
+	
+	/**
+	 * Remove a mapping from directory
+	 */
+	public void removeMapping(String key);
+	
+
+	/**
+	 * Lookup method maps key "id" to value
+	 */
+	public String lookup(String id);
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/registry/memory/VABInMemoryRegistry.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/registry/memory/VABInMemoryRegistry.java
new file mode 100644
index 0000000..08bc30e
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/registry/memory/VABInMemoryRegistry.java
@@ -0,0 +1,91 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.vab.registry.memory;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.eclipse.basyx.vab.registry.api.IVABRegistryService;
+
+
+
+/**
+ * Implement a in memory directory
+ * 
+ * @author kuhn
+ *
+ */
+public class VABInMemoryRegistry implements IVABRegistryService {
+
+	
+	/**
+	 * Map that stores key/value mappings
+	 */
+	protected Map<String, Object> keyToValue = new HashMap<>();
+	
+	
+		
+	
+	/**
+	 * Default constructor
+	 */
+	public VABInMemoryRegistry() {
+		// Do nothing
+	}
+	
+	
+	/**
+	 * Constructor that accepts initial entries
+	 */
+	public VABInMemoryRegistry(Map<String, String> addedValues) {
+		keyToValue.putAll(addedValues);
+	}
+	
+	
+	
+	/**
+	 * Add a mapping to directory
+	 */
+	@Override
+	public IVABRegistryService addMapping(String key, String value) {
+		keyToValue.put(key, value);
+		
+		// Return 'this' instance
+		return this;
+	}
+
+	/**
+	 * Add several mappings to directory
+	 */
+	public void addMappings(Map<String, String> mappings) {
+		keyToValue.putAll(mappings);
+	}
+	
+	/**
+	 * Remove a mapping from directory
+	 */
+	@Override
+	public void removeMapping(String key) {
+		keyToValue.remove(key);
+	}
+	
+	/**
+	 * Lookup method
+	 */
+	@Override
+	public String lookup(String id) {
+		if(keyToValue.containsKey(id)) {
+			return (String) keyToValue.get(id);
+		} else {
+			throw new ResourceNotFoundException("No entry exists for key " + id);
+		}
+	}
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/registry/proxy/VABRegistryProxy.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/registry/proxy/VABRegistryProxy.java
new file mode 100644
index 0000000..16cdb08
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/registry/proxy/VABRegistryProxy.java
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.vab.registry.proxy;
+
+import org.eclipse.basyx.vab.coder.json.connector.JSONConnector;
+import org.eclipse.basyx.vab.exception.provider.ProviderException;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnector;
+import org.eclipse.basyx.vab.registry.api.IVABRegistryService;
+
+public class VABRegistryProxy implements IVABRegistryService {
+	/**
+	 * Store the URL of the registry of this proxy
+	 */
+	protected IModelProvider provider;
+
+	/**
+	 * Constructor for a generic VAB directory proxy based on a HTTP connection
+	 * 
+	 * @param directoryUrl
+	 *            The endpoint of the registry with a HTTP-REST interface
+	 */
+	public VABRegistryProxy(String directoryUrl) {
+		this(new VABElementProxy("", new JSONConnector(new HTTPConnector(directoryUrl))));
+	}
+	
+	/**
+	 * Constructor for a generic VAB directory based on the registry model provider
+	 * 
+	 * @param provider
+	 *            A model provider for the actual registry
+	 */
+	public VABRegistryProxy(IModelProvider provider) {
+		this.provider = provider;
+	}
+
+	/**
+	 * Adds a single entry to the directory
+	 */
+	@Override
+	public IVABRegistryService addMapping(String key, String value) {
+		provider.createValue(key, value);
+		return this;
+	}
+
+	/**
+	 * Deletes an entry from the directory
+	 */
+	@Override
+	public void removeMapping(String key) {
+		provider.deleteValue(key);
+	}
+
+	/**
+	 * Returns a single entry in the directory
+	 */
+	@Override
+	public String lookup(String id) {
+		Object response = provider.getValue(id);
+		
+		if (response instanceof String) {
+			return (String) response;
+		} else {
+			throw new ProviderException("Lookup returned unexpected object: " + response);
+		}
+	}
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/registry/restapi/VABRegistryModelProvider.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/registry/restapi/VABRegistryModelProvider.java
new file mode 100644
index 0000000..1540570
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/registry/restapi/VABRegistryModelProvider.java
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.vab.registry.restapi;
+
+import org.eclipse.basyx.vab.exception.provider.ProviderException;
+import org.eclipse.basyx.vab.modelprovider.VABPathTools;
+import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
+import org.eclipse.basyx.vab.registry.api.IVABRegistryService;
+import org.eclipse.basyx.vab.registry.memory.VABInMemoryRegistry;
+
+/**
+ * Connects an arbitrary IVABDirectoryService implementation to the VAB
+ * 
+ * @author schnicke
+ */
+
+public class VABRegistryModelProvider implements IModelProvider {
+
+	private IVABRegistryService directory;
+
+	/**
+	 * Creates a DirectoryModelProvider wrapping an IVABDirectoryService
+	 * 
+	 * @param directory
+	 */
+	public VABRegistryModelProvider(IVABRegistryService directory) {
+		super();
+		this.directory = directory;
+	}
+
+	/**
+	 * Creates a default DirectoryModelProvider wrapping an InMemoryDirectory
+	 */
+	public VABRegistryModelProvider() {
+		this(new VABInMemoryRegistry());
+	}
+
+	@Override
+	public Object getValue(String path) throws ProviderException {
+		path = VABPathTools.stripSlashes(path);
+		return directory.lookup(path);
+	}
+
+	@Override
+	public void setValue(String path, Object newValue) throws ProviderException {
+		throw new RuntimeException("Set not supported by VAB Directory");
+	}
+
+	@Override
+	public void createValue(String path, Object newEntity) throws ProviderException {
+		path = VABPathTools.stripSlashes(path);
+		directory.addMapping(path, (String) newEntity);
+	}
+
+	@Override
+	public void deleteValue(String path) throws ProviderException {
+		path = VABPathTools.stripSlashes(path);
+		directory.removeMapping(path);
+	}
+
+	@Override
+	public void deleteValue(String path, Object obj) throws ProviderException {
+		throw new RuntimeException("Delete with parameter not supported by VAB Directory");
+	}
+
+	@Override
+	public Object invokeOperation(String path, Object... parameter) throws ProviderException {
+		throw new RuntimeException("Invoke not supported by VAB Directory");
+	}
+
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/service/api/BaSyxService.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/service/api/BaSyxService.java
index bd5dbbe..5e08d68 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/service/api/BaSyxService.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/service/api/BaSyxService.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.vab.service.api;
 
 
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/support/TypeDestroyer.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/support/TypeDestroyer.java
index c142792..0e3c2fd 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/support/TypeDestroyer.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/support/TypeDestroyer.java
@@ -1,8 +1,16 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.vab.support;
 
 import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
@@ -10,6 +18,9 @@
 
 /**
  * Removes type information similar to what a communication over VAB would do
+ * <br>
+ * Additionally, Sets are changed to Lists
+ * 
  * @author rajashek
  *
  */
@@ -40,8 +51,8 @@
 		}
 	}
 	
-	private static Set<Object> handleSet(Set<Object> set) {
-		Set<Object> ret = new HashSet<>();
+	private static List<Object> handleSet(Set<Object> set) {
+		List<Object> ret = new ArrayList<>();
 		for (Object o : set) {
 			ret.add(handle(o));
 		}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/support/TypeDestroyingProvider.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/support/TypeDestroyingProvider.java
index 443da13..90ba2bf 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/support/TypeDestroyingProvider.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/support/TypeDestroyingProvider.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.vab.support;
 
 import org.eclipse.basyx.vab.exception.provider.ProviderException;
@@ -19,13 +28,13 @@
 	}
 	
 	@Override
-	public Object getModelPropertyValue(String path) throws ProviderException {
-		return TypeDestroyer.handle(provider.getModelPropertyValue(path));
+	public Object getValue(String path) throws ProviderException {
+		return TypeDestroyer.handle(provider.getValue(path));
 	}
 
 	@Override
-	public void setModelPropertyValue(String path, Object newValue) throws ProviderException {
-		provider.setModelPropertyValue(path, newValue);
+	public void setValue(String path, Object newValue) throws ProviderException {
+		provider.setValue(path, newValue);
 	}
 
 	@Override
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/aggregator/AASAggregatorSuite.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/aggregator/AASAggregatorSuite.java
index 69ada6b..db54503 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/aggregator/AASAggregatorSuite.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/aggregator/AASAggregatorSuite.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.aas.aggregator;
 
 import static org.junit.Assert.assertEquals;
@@ -8,10 +17,15 @@
 
 import org.eclipse.basyx.aas.aggregator.api.IAASAggregator;
 import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.api.parts.asset.AssetKind;
 import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
 import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
+import org.eclipse.basyx.aas.metamodel.map.parts.Asset;
 import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
 import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangStrings;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 
@@ -25,7 +39,9 @@
 public abstract class AASAggregatorSuite {
 
 	protected AssetAdministrationShell aas1;
-	private static final String aas1Id = "aas1";
+
+	// Choose AAS Id that needs encoding due to '/'
+	private static final String aas1Id = "aas1/s";
 	private static final LangStrings description1 = new LangStrings("en", "This is test AAS 1");
 	private static final String aas1Category = "TestCategory1";
 	private static final String aas1AltCategory = "OtherTestCategory1";
@@ -38,21 +54,22 @@
 	// initializing dummy test data
 	@Before
 	public void initAASDummies() {
-		aas1 = new AssetAdministrationShell();
-		aas1.setIdentification(IdentifierType.CUSTOM, aas1Id);
-		aas1.setIdShort(aas1Id);
+		aas1 = new AssetAdministrationShell(aas1Id, new Identifier(IdentifierType.CUSTOM, aas1Id), new Asset("asset1IdShort", new Identifier(IdentifierType.CUSTOM, "asset1"), AssetKind.INSTANCE));
 		aas1.setDescription(description1);
 		aas1.setCategory(aas1Category);
 		
-		aas2 = new AssetAdministrationShell();
-		aas2.setIdentification(IdentifierType.CUSTOM, aas2Id);
-		aas2.setIdShort(aas2Id);
+		aas2 = new AssetAdministrationShell(aas2Id, new Identifier(IdentifierType.CUSTOM, aas2Id), new Asset("asset2IdShort", new Identifier(IdentifierType.CUSTOM, "asset2"), AssetKind.INSTANCE));
 		aas2.setDescription(description2);
 		aas2.setCategory(aas2Category);
 	}
 	
 	protected abstract IAASAggregator getAggregator();
 	
+	@Before
+	public void clearAASAggregator() {
+		IAASAggregator aggregator = getAggregator();
+		aggregator.getAASList().stream().map(a -> a.getIdentification()).forEach(id -> aggregator.deleteAAS(id));
+	}
 	
 	@Test
 	public void testCreateAndGetAAS() {
@@ -62,7 +79,8 @@
 		aggregator.createAAS(aas1);
 		
 		//get and check the created AAS
-		checkAAS1(aggregator.getAAS(new ModelUrn(aas1Id)));
+		IAssetAdministrationShell retrieved = aggregator.getAAS(aas1.getIdentification());
+		checkAAS1(retrieved);
 	}
 	
 	@Test
@@ -140,10 +158,34 @@
 		}
 	}
 	
+	@Test(expected = ResourceNotFoundException.class)
+	public void deleteNotExistingAAS() {
+		getAggregator().getAAS(new Identifier(IdentifierType.CUSTOM, "IDontExist"));
+	}
+
+	@After
+	public void deleteExistingAAS() {
+		IAASAggregator aggregator = getAggregator();
+
+		// Delete aas1 if exists
+		try {
+			aggregator.deleteAAS(new ModelUrn(aas1Id));
+		} catch (ResourceNotFoundException e) {
+			// do nothing
+		}
+
+		// Delete aas2 if exists
+		try {
+			aggregator.deleteAAS(new ModelUrn(aas2Id));
+		} catch (ResourceNotFoundException e) {
+			// do nothing
+		}
+	}
+
 	// Methods to verify, that AAS objects contain the correct test data
 	private void checkAAS1(Object o) {
-		assertTrue(o instanceof AssetAdministrationShell);
-		AssetAdministrationShell aas = (AssetAdministrationShell) o;
+		assertTrue(o instanceof IAssetAdministrationShell);
+		IAssetAdministrationShell aas = (IAssetAdministrationShell) o;
 		
 		assertEquals(aas1Id, aas.getIdShort());
 		assertEquals(aas1Id, aas.getIdentification().getId());
@@ -152,8 +194,8 @@
 	}
 	
 	private void checkAAS2(Object o) {
-		assertTrue(o instanceof AssetAdministrationShell);
-		AssetAdministrationShell aas = (AssetAdministrationShell) o;
+		assertTrue(o instanceof IAssetAdministrationShell);
+		IAssetAdministrationShell aas = (IAssetAdministrationShell) o;
 		
 		assertEquals(aas2Id, aas.getIdShort());
 		assertEquals(aas2Id, aas.getIdentification().getId());
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/aggregator/TestAASAggregator.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/aggregator/TestAASAggregator.java
index bc1a757..3e838b1 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/aggregator/TestAASAggregator.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/aggregator/TestAASAggregator.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.aas.aggregator;
 
 import org.eclipse.basyx.aas.aggregator.AASAggregator;
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/aggregator/TestAASAggregatorProvider.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/aggregator/TestAASAggregatorProvider.java
deleted file mode 100644
index 42706ec..0000000
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/aggregator/TestAASAggregatorProvider.java
+++ /dev/null
@@ -1,111 +0,0 @@
-package org.eclipse.basyx.testsuite.regression.aas.aggregator;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.util.Map;
-
-import org.eclipse.basyx.aas.aggregator.AASAggregator;
-import org.eclipse.basyx.aas.aggregator.api.IAASAggregator;
-import org.eclipse.basyx.aas.aggregator.proxy.AASAggregatorProxy;
-import org.eclipse.basyx.aas.aggregator.restapi.AASAggregatorProvider;
-import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
-import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation;
-import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
-import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
-import org.eclipse.basyx.vab.modelprovider.VABPathTools;
-import org.junit.Test;
-
-/**
- * Test for the AASAggregationProvider
- * 
- * @author conradi, schnicke
- *
- */
-public class TestAASAggregatorProvider extends AASAggregatorSuite {
-
-	@Override
-	protected IAASAggregator getAggregator() {
-		return new AASAggregatorProxy(new AASAggregatorProvider(new AASAggregator()));
-	}
-
-	/**
-	 * Requests like /aasList/${aasId}/aas need to be fed through correctly. This
-	 * behaviour is tested here.
-	 */
-	@SuppressWarnings("unchecked")
-	@Test
-	public void testFeedThrough() {
-		AASAggregator aggregator = new AASAggregator();
-		aggregator.createAAS(aas1);
-		AASAggregatorProvider provider = new AASAggregatorProvider(aggregator);
-
-		// Test feedthrough of GET
-		String aasPath = "/aasList/" + aas1.getIdentification().getId() + "/aas";
-		AssetAdministrationShell retrievedAAS = retrieveAAS(provider, aasPath);
-		assertEquals(aas1.getIdentification(), retrievedAAS.getIdentification());
-
-		// Test feedthrough of CREATE
-		SubModel sm = new SubModel();
-		sm.setIdentification(IdentifierType.CUSTOM, "smId");
-		sm.setIdShort("smIdShort");
-		Operation op = new Operation((o) -> {
-			return true;
-		});
-		op.setIdShort("op");
-		sm.addSubModelElement(op);
-
-		Property prop = new Property(5);
-		prop.setIdShort("prop");
-		sm.addSubModelElement(prop);
-
-		provider.createValue(aasPath + "/submodels", sm);
-
-		// Check if it was created
-		String smPath = aasPath + "/submodels/smIdShort";
-		SubModel retrievedSm = SubModel.createAsFacade((Map<String, Object>) provider.getModelPropertyValue(smPath));
-		assertEquals(sm.getIdShort(), retrievedSm.getIdShort());
-
-		// Test feedthrough of SET
-		String propValuePath = VABPathTools.concatenatePaths(smPath, SubmodelElementProvider.PROPERTIES, prop.getIdShort(), "value");
-		int expectedPropValue = 20;
-		provider.setModelPropertyValue(propValuePath, expectedPropValue);
-
-		Map<String, Object> value = (Map<String, Object>) provider.getModelPropertyValue(propValuePath);
-		assertEquals(expectedPropValue, value.get(Property.VALUE));
-
-		// Test feedthrough of INVOKE
-		assertTrue((boolean) provider.invokeOperation(smPath + "/operations/op"));
-		
-		// Test feedthrough of DELETE
-		provider.deleteValue(smPath);
-
-		// Ensure only the submodel has been deleted
-		retrievedAAS = retrieveAAS(provider, aasPath);
-		assertEquals(aas1.getIdentification(), retrievedAAS.getIdentification());
-
-		try {
-			provider.getModelPropertyValue(smPath);
-			fail();
-		} catch (ResourceNotFoundException e) {
-			// Expected
-		}
-
-	}
-
-	/**
-	 * Retrieves the AAS given residing in the passed path on the passed provider
-	 * 
-	 * @param provider
-	 * @param aasPath
-	 * @return
-	 */
-	@SuppressWarnings("unchecked")
-	private AssetAdministrationShell retrieveAAS(AASAggregatorProvider provider, String aasPath) {
-		return AssetAdministrationShell.createAsFacade((Map<String, Object>) provider.getModelPropertyValue(aasPath));
-	}
-}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/aggregator/TestAASAggregatorProxy.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/aggregator/TestAASAggregatorProxy.java
new file mode 100644
index 0000000..00a6fc5
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/aggregator/TestAASAggregatorProxy.java
@@ -0,0 +1,96 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.aas.aggregator;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.eclipse.basyx.aas.aggregator.AASAggregator;
+import org.eclipse.basyx.aas.aggregator.api.IAASAggregator;
+import org.eclipse.basyx.aas.aggregator.proxy.AASAggregatorProxy;
+import org.eclipse.basyx.aas.aggregator.restapi.AASAggregatorProvider;
+import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperation;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+import org.junit.Test;
+
+/**
+ * Test for the AASAggregationProvider
+ * 
+ * @author conradi, schnicke
+ *
+ */
+public class TestAASAggregatorProxy extends AASAggregatorSuite {
+
+	@Override
+	protected IAASAggregator getAggregator() {
+		return new AASAggregatorProxy(new VABElementProxy("/shells", new AASAggregatorProvider(new AASAggregator())));
+	}
+
+	/**
+	 * Requests like /shells/${aasId}/aas need to be fed through correctly. This
+	 * behaviour is tested here.
+	 */
+	@Test
+	public void testFeedThrough() throws Exception {
+		IAASAggregator aggregator = getAggregator();
+		aggregator.createAAS(aas1);
+
+		// Test feedthrough of GET
+		IAssetAdministrationShell retrievedAAS = aggregator.getAAS(aas1.getIdentification());
+		assertEquals(aas1.getIdentification(), retrievedAAS.getIdentification());
+
+		// Test feedthrough of CREATE
+		Submodel sm = new Submodel();
+		sm.setIdentification(IdentifierType.CUSTOM, "smId");
+		sm.setIdShort("smIdShort");
+		Operation op = new Operation((o) -> {
+			return true;
+		});
+		op.setIdShort("op");
+		sm.addSubmodelElement(op);
+
+		Property prop = new Property(5);
+		prop.setIdShort("prop");
+		sm.addSubmodelElement(prop);
+
+		retrievedAAS.addSubmodel(sm);
+
+		// Check if it was created
+		ISubmodel retrievedSm = retrievedAAS.getSubmodels().get(sm.getIdShort());
+		assertEquals(sm.getIdShort(), retrievedSm.getIdShort());
+
+		// Test feedthrough of SET
+		int expectedPropValue = 20;
+		IProperty connectedProp = (IProperty) retrievedSm.getSubmodelElement(prop.getIdShort());
+
+		connectedProp.setValue(expectedPropValue);
+		assertEquals(expectedPropValue, connectedProp.getValue());
+
+		// Test feedthrough of INVOKE
+		// Use short form of invoke with operation variable matching and no parameters (empty object array)
+		assertTrue((boolean) ((IOperation) sm.getSubmodelElement(op.getIdShort())).invoke(new Object[0]));
+
+		// Test feedthrough of DELETE
+		retrievedAAS.removeSubmodel(sm.getIdentification());
+
+		// Ensure only the submodel has been deleted
+		assertEquals(aas1.getIdentification(), retrievedAAS.getIdentification());
+
+		assertFalse(retrievedAAS.getSubmodels().containsKey(sm.getIdShort()));
+	}
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/factory/aasx/AASXFactoryTest.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/factory/aasx/AASXFactoryTest.java
new file mode 100644
index 0000000..6a6925c
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/factory/aasx/AASXFactoryTest.java
@@ -0,0 +1,163 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.aas.factory.aasx;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+
+import org.eclipse.basyx.aas.factory.aasx.AASXFactory;
+import org.eclipse.basyx.aas.factory.aasx.InMemoryFile;
+import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.api.parts.asset.AssetKind;
+import org.eclipse.basyx.aas.metamodel.api.parts.asset.IAsset;
+import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
+import org.eclipse.basyx.aas.metamodel.map.parts.Asset;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.api.parts.IConceptDescription;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.File;
+import org.eclipse.basyx.vab.modelprovider.VABPathTools;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Test for the AASXFactory
+ * 
+ * @author conradi
+ *
+ */
+public class AASXFactoryTest {
+
+	private static final String XML_PATH = "aasx/xml/content.xml";
+	private static final String ORIGIN_PATH = "aasx/aasx-origin";
+	
+	
+	private AssetAdministrationShell aas;
+	private Submodel sm1;
+	private Submodel sm2;
+	
+	private List<IAssetAdministrationShell> aasList = new ArrayList<>();
+	private List<ISubmodel> submodelList = new ArrayList<>();
+	private List<IAsset> assetList = new ArrayList<>();
+	private List<IConceptDescription> conceptDescriptionList = new ArrayList<>();
+
+	private List<InMemoryFile> fileList = new ArrayList<>();
+	
+	
+	
+	@Before
+	public void setup() throws IOException {
+		Asset asset = new Asset("asset-id", new ModelUrn("ASSET_IDENTIFICATION"), AssetKind.TYPE);
+		aas = new AssetAdministrationShell("aas-id", new ModelUrn("AAS_IDENTIFICATION"), asset);
+		
+		sm1 = new Submodel("sm1", new ModelUrn("SM1_ID"));
+		sm2 = new Submodel("sm2", new ModelUrn("SM2_ID"));
+		
+		File file1 = new File("http://localhost:8080/image.png", "image/png");
+		file1.setIdShort("file1");
+		File file2 = new File("aasx/Document/docu.pdf", "application/pdf");
+		file2.setIdShort("file2");
+		File file3 = new File("/aasx/Document/docu2.pdf", "application/pdf");
+		file3.setIdShort("file3");
+		
+		
+		
+		SubmodelElementCollection collection = new SubmodelElementCollection("collection");
+		collection.addSubmodelElement(file2);
+		
+		sm1.addSubmodelElement(file1);
+		sm1.addSubmodelElement(collection);
+		sm2.addSubmodelElement(file3);
+		
+		aas.addSubmodel(sm1);
+		aas.addSubmodel(sm2);
+		
+		aasList.add(aas);
+		submodelList.add(sm1);
+		submodelList.add(sm2);
+		assetList.add(asset);
+		
+		
+		byte[] content1 = {0,1,2,3,4};
+		InMemoryFile file = new InMemoryFile(content1, "/image.png");
+		fileList.add(file);
+		
+		byte[] content2 = {5,6,7,8,9};
+		file = new InMemoryFile(content2, "/aasx/Document/docu.pdf");
+		fileList.add(file);
+		
+		byte[] content3 = {10,11,12,13,14};
+		file = new InMemoryFile(content3, "aasx/Document/docu2.pdf");
+		fileList.add(file);
+	}
+	
+	
+	@Test
+	public void testBuildAASX() throws IOException, TransformerException, ParserConfigurationException {
+		
+		// This stream can be used to write the .aasx directly to a file
+		// FileOutputStream out = new FileOutputStream("path/to/test.aasx");
+		
+		// This stream keeps the output of the AASXFactory only in memory
+		ByteArrayOutputStream out = new ByteArrayOutputStream();
+		
+		AASXFactory.buildAASX(aasList, assetList, conceptDescriptionList, submodelList, fileList, out);
+		
+		validateAASX(out);
+		
+	}
+	
+	
+	private void validateAASX(ByteArrayOutputStream byteStream) throws IOException {
+		ZipInputStream in = new ZipInputStream(new ByteArrayInputStream(byteStream.toByteArray()));
+		ZipEntry zipEntry = null;
+
+		ArrayList<String> filePaths = new ArrayList<>();
+		
+		while((zipEntry = in.getNextEntry()) != null) {
+			if(zipEntry.getName().equals(XML_PATH)) {
+				
+				// Read the first 5 bytes of the XML file to make sure it is in fact XML file
+				// No further test of XML file necessary as XML-Converter is tested separately
+				byte[] buf = new byte[5];
+				in.read(buf);
+				assertEquals("<?xml", new String(buf));
+				
+			}
+			
+			// Write the paths of all files contained in the .aasx into filePaths
+			filePaths.add(zipEntry.getName());
+		}
+		
+		assertTrue(filePaths.contains(XML_PATH));
+		assertTrue(filePaths.contains(ORIGIN_PATH));
+		
+		// Check if all expected files are present
+		// Needs to strip the first slash of the paths, as ZipEntry gives paths without it
+		for(InMemoryFile file: fileList) {
+			assertTrue(filePaths.contains(VABPathTools.stripSlashes(file.getPath())));
+		}
+		
+	}
+	
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/factory/json/TestJSONConverter.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/factory/json/TestJSONConverter.java
new file mode 100644
index 0000000..b72744c
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/factory/json/TestJSONConverter.java
@@ -0,0 +1,129 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.aas.factory.json;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.List;
+
+import org.eclipse.basyx.aas.factory.json.JSONToMetamodelConverter;
+import org.eclipse.basyx.aas.factory.json.MetamodelToJSONConverter;
+import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.map.parts.Asset;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.parts.ConceptDescription;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Test for MetamodelToJSONConverter and JSONToMetamodelConverter
+ * 
+ * @author conradi
+ *
+ */
+public class TestJSONConverter {
+
+	private String jsonPath = "src/test/resources/aas/factory/json/aasJsonSchemaV2.0.1_Example.json";
+	
+	private JSONToMetamodelConverter converter;
+	
+	@Before
+	public void buildConverter() throws IOException {
+		String json = new String(Files.readAllBytes(Paths.get(jsonPath)));
+		converter = new JSONToMetamodelConverter(json);
+	}
+	
+	@Test
+	public void testParseAAS() {
+		checkAASs(converter.parseAAS());
+	}
+	
+	@Test
+	public void testParseSubmodels() {
+		checkSubmodels(converter.parseSubmodels());		
+	}
+	
+	@Test
+	public void testParseAssets() {
+		checkAssets(converter.parseAssets());
+	}
+	
+	@Test
+	public void testParseConceptDescriptions() {
+		checkConceptDescriptions(converter.parseConceptDescriptions());
+	}
+	
+	@Test
+	public void testBuildJSON() {
+		
+		// Read Metamodel-Objects from JSON-File
+		List<AssetAdministrationShell> aasList = converter.parseAAS();
+		List<Asset> assetList = converter.parseAssets();
+		List<ConceptDescription> conceptDescriptionList = converter.parseConceptDescriptions();
+		List<Submodel> submodelList = converter.parseSubmodels();
+		
+		// Convert Metamodel-Objects to JSON
+		String json = MetamodelToJSONConverter.convertToJSON(aasList, assetList, conceptDescriptionList, submodelList);
+		
+		// Convert new JSON back to Metamodel-Objects to check them
+		JSONToMetamodelConverter converter2 = new JSONToMetamodelConverter(json);
+		
+		// Check if the Metamodel-Objects are still correct
+		checkAASs(converter2.parseAAS());
+		checkAssets(converter2.parseAssets());
+		checkConceptDescriptions(converter2.parseConceptDescriptions());
+		checkSubmodels(converter2.parseSubmodels());
+	}
+	
+	
+
+	private void checkAASs(List<AssetAdministrationShell> aasList) {
+		assertEquals(1, aasList.size());
+		AssetAdministrationShell aas = aasList.get(0);
+		
+		assertEquals("ExampleMotor", aas.getIdShort());
+		assertEquals(3, aas.getSubmodelReferences().size());
+		assertEquals("http://customer.com/aas/9175_7013_7091_9168", aas.getIdentification().getId());
+	}
+	
+	private void checkSubmodels(List<Submodel> smList) {
+		assertEquals(3, smList.size());
+		
+		Submodel sm = smList.stream().filter(c -> c.getIdShort().equals("TechnicalData")).findAny().get();
+		
+		assertEquals(1, sm.getSubmodelElements().size());
+		
+		Property smElement = (Property) sm.getSubmodelElements().get("MaxRotationSpeed");
+		assertEquals("5000", smElement.getValue());
+	}
+	
+	private void checkAssets(List<Asset> assetList) {
+		assertEquals(1, assetList.size());
+		Asset asset = assetList.get(0);
+		
+		assertEquals("ServoDCMotor", asset.getIdShort());
+		assertEquals("http://customer.com/assets/KHBVZJSQKIY", asset.getIdentification().getId());
+	}
+	
+	private void checkConceptDescriptions(List<ConceptDescription> conceptDescriptionList) {
+		assertEquals(5, conceptDescriptionList.size());
+		
+		ConceptDescription cd = conceptDescriptionList.stream()
+				.filter(c -> c.getIdShort().equals("DigitalFile")).findAny().get();
+		
+		assertEquals("www.vdi2770.com/blatt1/Entwurf/Okt18/cd/StoredDocumentRepresentation/DigitalFile",
+				cd.getIdentification().getId());
+	}
+	
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/factory/xml/TestXMLConverter.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/factory/xml/TestXMLConverter.java
index 087dd33..47ce3c5 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/factory/xml/TestXMLConverter.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/factory/xml/TestXMLConverter.java
@@ -1,16 +1,23 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.aas.factory.xml;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
 
 import java.io.StringWriter;
 import java.nio.file.Files;
 import java.nio.file.Paths;
 import java.util.ArrayList;
-import java.util.Base64;
 import java.util.Collection;
 import java.util.List;
 import java.util.Map;
@@ -25,7 +32,7 @@
 import org.eclipse.basyx.aas.metamodel.api.parts.asset.IAsset;
 import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
 import org.eclipse.basyx.aas.metamodel.map.parts.Asset;
-import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
 import org.eclipse.basyx.submodel.metamodel.api.dataspecification.IDataSpecificationContent;
 import org.eclipse.basyx.submodel.metamodel.api.dataspecification.IEmbeddedDataSpecification;
 import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
@@ -37,9 +44,10 @@
 import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
 import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyType;
 import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IDataElement;
 import org.eclipse.basyx.submodel.metamodel.api.submodelelement.entity.EntityType;
 import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperationVariable;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
 import org.eclipse.basyx.submodel.metamodel.map.dataspecification.DataSpecificationIEC61360Content;
 import org.eclipse.basyx.submodel.metamodel.map.parts.ConceptDescription;
 import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangStrings;
@@ -47,12 +55,14 @@
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.Blob;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.File;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.MultiLanguageProperty;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.Range;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.ReferenceElement;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.range.Range;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.entity.Entity;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.event.BasicEvent;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.relationship.AnnotatedRelationshipElement;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.relationship.RelationshipElement;
 import org.eclipse.basyx.vab.model.VABModelMap;
 import org.eclipse.basyx.vab.support.TypeDestroyer;
@@ -66,101 +76,70 @@
 	private XMLToMetamodelConverter converter;
 	
 	@Before
-	public void buildConverter() {
-		try {
-			String xml = new String(Files.readAllBytes(Paths.get(xmlInPath)));
-			converter = new XMLToMetamodelConverter(xml);
-		} catch (Exception e) {
-			e.printStackTrace();
-			fail();
-		}
+	public void buildConverter() throws Exception {
+		String xml = new String(Files.readAllBytes(Paths.get(xmlInPath)));
+		converter = new XMLToMetamodelConverter(xml);
 	}
 
 	@Test
-	public void testParseAAS() {
-		try {
-			checkAASs(converter.parseAAS());
-		} catch (Exception e) {
-			e.printStackTrace();
-			fail();
-		}
+	public void testParseAAS() throws Exception {
+		checkAASs(converter.parseAAS());
 	}
 	
 	@Test
-	public void testParseAssets() {
-		try {
-			checkAssets(converter.parseAssets());
-		} catch (Exception e) {
-			e.printStackTrace();
-			fail();
-		}
+	public void testParseAssets() throws Exception {
+		checkAssets(converter.parseAssets());
 	}
 	
 	@Test
 	public void testParseConceptDescriptions() {
-		try {
-			checkConceptDescriptions(converter.parseConceptDescriptions());
-		} catch (Exception e) {
-			e.printStackTrace();
-			fail();
-		}
+		checkConceptDescriptions(converter.parseConceptDescriptions());
 	}
 	
 	@Test
 	public void testParseSubmodels() {
-		try {
-			checkSubmodels(converter.parseSubmodels());			
-		} catch (Exception e) {
-			e.printStackTrace();
-			fail();
-		}
+		checkSubmodels(converter.parseSubmodels());
 	}
 	
 	@Test
-	public void testBuildXML() {
-		try {
-			//Convert the in.xml to Objects
-			List<IAssetAdministrationShell> assetAdministrationShellList = converter.parseAAS();
-			List<IAsset> assetList = converter.parseAssets();
-			List<IConceptDescription> conceptDescriptionList = converter.parseConceptDescriptions();
-			List<ISubModel> submodelList = converter.parseSubmodels();
-			
-			//Build XML-File from the Objects and write it to a StringWriter
-			StringWriter resultWithTypes = new StringWriter();
-			MetamodelToXMLConverter.convertToXML(assetAdministrationShellList, assetList, conceptDescriptionList, submodelList, new StreamResult(resultWithTypes));
-			
-			
-			//Read the content of the StringWriter, convert it into Objects and check them
-			XMLToMetamodelConverter converterWithTypes = new XMLToMetamodelConverter(resultWithTypes.toString());
-
-			checkAASs(converterWithTypes.parseAAS());
-			checkAssets(converterWithTypes.parseAssets());
-			checkConceptDescriptions(converterWithTypes.parseConceptDescriptions());
-			checkSubmodels(converterWithTypes.parseSubmodels());
-			
-			//erase the types of the Objects, that they are plain Maps as if they were transferred over the VAB
-			List<IAssetAdministrationShell> iAssetAdministrationShellList = destroyAASTypes(assetAdministrationShellList);
-			List<IAsset> iAssetList = destroyAssetTypes(assetList);
-			List<IConceptDescription> iConceptDescriptionList = destroyConceptDescriptionTypes(conceptDescriptionList);
-			List<ISubModel> iSubmodelList = destroySubmodelTypes(submodelList);
-			
-			//Build XML-File from the Objects and write it to a StringWriter
-			StringWriter resultWithoutTypes = new StringWriter();
-			MetamodelToXMLConverter.convertToXML(iAssetAdministrationShellList, iAssetList, iConceptDescriptionList, iSubmodelList, new StreamResult(resultWithoutTypes));
-			
-			
-			//Read the content of the StringWriter, convert it into Objects and check them
-			XMLToMetamodelConverter converterWithoutTypes = new XMLToMetamodelConverter(resultWithoutTypes.toString());
-			
-			checkAASs(converterWithoutTypes.parseAAS());
-			checkAssets(converterWithoutTypes.parseAssets());
-			checkConceptDescriptions(converterWithoutTypes.parseConceptDescriptions());
-			checkSubmodels(converterWithoutTypes.parseSubmodels());
-			
-		} catch (Exception e) {
-			e.printStackTrace();
-			fail();
-		}
+	public void testBuildXML() throws Exception {
+		//Convert the in.xml to Objects
+		List<IAssetAdministrationShell> assetAdministrationShellList = converter.parseAAS();
+		List<IAsset> assetList = converter.parseAssets();
+		List<IConceptDescription> conceptDescriptionList = converter.parseConceptDescriptions();
+		List<ISubmodel> submodelList = converter.parseSubmodels();
+		
+		//Build XML-File from the Objects and write it to a StringWriter
+		StringWriter resultWithTypes = new StringWriter();
+		MetamodelToXMLConverter.convertToXML(assetAdministrationShellList, assetList, conceptDescriptionList, submodelList, new StreamResult(resultWithTypes));
+		
+		
+		//Read the content of the StringWriter, convert it into Objects and check them
+		XMLToMetamodelConverter converterWithTypes = new XMLToMetamodelConverter(resultWithTypes.toString());
+	
+		checkAASs(converterWithTypes.parseAAS());
+		checkAssets(converterWithTypes.parseAssets());
+		checkConceptDescriptions(converterWithTypes.parseConceptDescriptions());
+		checkSubmodels(converterWithTypes.parseSubmodels());
+		
+		//erase the types of the Objects, that they are plain Maps as if they were transferred over the VAB
+		List<IAssetAdministrationShell> iAssetAdministrationShellList = destroyAASTypes(assetAdministrationShellList);
+		List<IAsset> iAssetList = destroyAssetTypes(assetList);
+		List<IConceptDescription> iConceptDescriptionList = destroyConceptDescriptionTypes(conceptDescriptionList);
+		List<ISubmodel> iSubmodelList = destroySubmodelTypes(submodelList);
+		
+		//Build XML-File from the Objects and write it to a StringWriter
+		StringWriter resultWithoutTypes = new StringWriter();
+		MetamodelToXMLConverter.convertToXML(iAssetAdministrationShellList, iAssetList, iConceptDescriptionList, iSubmodelList, new StreamResult(resultWithoutTypes));
+		
+		
+		//Read the content of the StringWriter, convert it into Objects and check them
+		XMLToMetamodelConverter converterWithoutTypes = new XMLToMetamodelConverter(resultWithoutTypes.toString());
+		
+		checkAASs(converterWithoutTypes.parseAAS());
+		checkAssets(converterWithoutTypes.parseAssets());
+		checkConceptDescriptions(converterWithoutTypes.parseConceptDescriptions());
+		checkSubmodels(converterWithoutTypes.parseSubmodels());
 	}
 	
 	private void checkAASs(List<IAssetAdministrationShell> aasList) {
@@ -320,7 +299,7 @@
 		assertEquals("3s7plfdrs35_asset1", asset.getIdShort());
 		assertEquals("asset1_Description", asset.getDescription().get("EN"));
 		assertEquals(IdentifierType.IRI, asset.getIdentification().getIdType());
-		assertEquals("Instance", asset.getAssetKind().toString());
+		assertEquals("Type", asset.getAssetKind().toString());
 		assertEquals("www.festo.com/dic/08111234", asset.getAssetIdentificationModel().getKeys().get(0).getValue());
 	}
 	
@@ -340,12 +319,12 @@
 		assertEquals(1, refs.size());
 	}
 	
-	private void checkSubmodels(List<ISubModel> submodels) {
+	private void checkSubmodels(List<ISubmodel> submodels) {
 		assertEquals(2, submodels.size());
-		ISubModel submodel = null;
+		ISubmodel submodel = null;
 		
-		//select the SubModel with a specific ID form the list
-		for(ISubModel s: submodels) {
+		//select the Submodel with a specific ID form the list
+		for(ISubmodel s: submodels) {
 			if(s.getIdShort().equals("3s7plfdrs35_submodel1")) {
 				submodel = s;
 				break;
@@ -355,34 +334,37 @@
 		assertNotNull(submodel);
 		checkDefaultEmbeddedDataSpecification(submodel);
 		assertEquals("3s7plfdrs35_submodel1", submodel.getIdShort());
-		Collection<IConstraint> constraints = submodel.getQualifier();
-		assertEquals(2, constraints.size());
+		Collection<IConstraint> constraints = submodel.getQualifiers();
+		assertEquals(4, constraints.size());
 		checkSubmodelElements(submodel);
 	}
 	
 	@SuppressWarnings("unchecked")
-	private void checkSubmodelElements(ISubModel submodel) {
+	private void checkSubmodelElements(ISubmodel submodel) {
 		Map<String, ISubmodelElement> submodelElements = (Map<String, ISubmodelElement>)
-				((Map<String, Object>)submodel).get(SubModel.SUBMODELELEMENT);
-		assertEquals(12, submodelElements.size());
+				((Map<String, Object>)submodel).get(Submodel.SUBMODELELEMENT);
+		assertEquals(13, submodelElements.size());
 		
 		ISubmodelElement element = submodelElements.get("rotationSpeed");
 		assertTrue(element instanceof Property);
 		Property property = (Property) element;
 		checkDefaultEmbeddedDataSpecification(property);
-		assertEquals("2000", property.get());
-		assertEquals("double", property.getValueType());
+		List<IKey> keys = property.getValueId().getKeys();
+		assertEquals(1, keys.size());
+		assertEquals("0173-1#05-AAA650#002", keys.get(0).getValue());
+		assertEquals(2000.0, property.getValue());
+		assertEquals(ValueType.Double, property.getValueType());
 		assertEquals("rotationSpeed", property.getIdShort());
 		
 		element = submodelElements.get("emptyDouble");
 		assertTrue(element instanceof Property);
 		property = (Property) element;
-		assertEquals("double", property.getValueType());
+		assertEquals(ValueType.Double, property.getValueType());
 		
 		element = submodelElements.get("basic_event_id");
 		assertTrue(element instanceof BasicEvent);
 		BasicEvent basicEvent = (BasicEvent) element;
-		List<IKey> keys = basicEvent.getObserved().getKeys();
+		keys = basicEvent.getObserved().getKeys();
 		assertEquals(1, keys.size());
 		assertEquals("http://www.zvei.de/demo/submodelDefinitions/87654346", keys.get(0).getValue());
 		
@@ -408,7 +390,7 @@
 		element = submodelElements.get("range_id");
 		assertTrue(element instanceof Range);
 		Range range = (Range) element;
-		assertEquals("int", range.getValueType());
+		assertEquals(ValueType.Integer, range.getValueType());
 		assertEquals("1", range.getMin());
 		assertEquals("10", range.getMax());
 		
@@ -422,7 +404,7 @@
 		assertTrue(element instanceof Blob);
 		Blob blob = (Blob) element;
 		assertEquals("blob_mimetype", blob.getMimeType());
-		assertEquals("YmxvYit2YWx1ZQ==", Base64.getEncoder().encodeToString(blob.getValue()));
+		assertEquals("YmxvYit2YWx1ZQ==", blob.getValue());
 		
 		element = submodelElements.get("reference_ELE_ID");
 		assertTrue(element instanceof ReferenceElement);
@@ -449,6 +431,21 @@
 		assertEquals(1, keys.size());
 		assertEquals("0173-1#05-AAA650#002", keys.get(0).getValue());
 		
+		element = submodelElements.get("annotatedRelationshipElement_ID");
+		assertTrue(element instanceof AnnotatedRelationshipElement);
+		AnnotatedRelationshipElement annotatedElem = (AnnotatedRelationshipElement) element;
+		keys = annotatedElem.getFirst().getKeys();
+		assertEquals(1, keys.size());
+		assertEquals("0173-1#05-AAA650#003", keys.get(0).getValue());
+		keys = annotatedElem.getSecond().getKeys();
+		assertEquals(1, keys.size());
+		assertEquals("0173-1#05-AAA650#004", keys.get(0).getValue());
+		Collection<IDataElement> annotations = annotatedElem.getValue().getAnnotations();
+		assertEquals(2, annotations.size());
+		for(IDataElement annotationElement: annotations) {
+			assertTrue(annotationElement instanceof Property);
+		}
+		
 		element = submodelElements.get("operation_ID");
 		assertTrue(element instanceof Operation);
 		Operation op = (Operation) element;
@@ -474,10 +471,10 @@
 	}
 	
 	@SuppressWarnings("unchecked")
-	private List<ISubModel> destroySubmodelTypes(List<ISubModel> submodelList) {
-		List<ISubModel> ret = new ArrayList<>();
-		for(ISubModel submodel: submodelList) {
-			ret.add(SubModel.createAsFacade(new VABModelMap<>(TypeDestroyer.destroyType((Map<String, Object>) submodel))));
+	private List<ISubmodel> destroySubmodelTypes(List<ISubmodel> submodelList) {
+		List<ISubmodel> ret = new ArrayList<>();
+		for(ISubmodel submodel: submodelList) {
+			ret.add(Submodel.createAsFacade(new VABModelMap<>(TypeDestroyer.destroyType((Map<String, Object>) submodel))));
 		}
 		return ret;
 	}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/manager/TestAASHTTP.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/manager/TestAASHTTP.java
index 4bb1648..fff8642 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/manager/TestAASHTTP.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/manager/TestAASHTTP.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.aas.manager;
 
 import static org.junit.Assert.assertEquals;
@@ -10,15 +19,15 @@
 import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
 import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
 import org.eclipse.basyx.aas.registration.memory.InMemoryRegistry;
-import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
 import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
 import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
 import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperation;
 import org.eclipse.basyx.testsuite.regression.aas.restapi.StubAASServlet;
 import org.eclipse.basyx.testsuite.regression.vab.protocol.http.AASHTTPServerResource;
-import org.eclipse.basyx.vab.directory.memory.InMemoryDirectory;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorFactory;
 import org.eclipse.basyx.vab.protocol.http.server.BaSyxContext;
+import org.eclipse.basyx.vab.registry.memory.VABInMemoryRegistry;
 import org.junit.Before;
 import org.junit.ClassRule;
 import org.junit.Test;
@@ -49,10 +58,10 @@
 	@Before
 	public void build() {
 		// Fill directory stub
-		InMemoryDirectory directory = new InMemoryDirectory();
+		VABInMemoryRegistry directory = new VABInMemoryRegistry();
 		directory.addMapping(StubAASServlet.AASURN.getId(), "http://localhost:8080/basys.sdk/Testsuite/StubAAS/aas");
 		directory.addMapping(StubAASServlet.SMURN.getId(),
-				"http://localhost:8080/basys.sdk/Testsuite/StubAAS/aas/submodels/" + StubAASServlet.SMIDSHORT);
+				"http://localhost:8080/basys.sdk/Testsuite/StubAAS/aas/submodels/" + StubAASServlet.SMIDSHORT + "/submodel");
 
 		InMemoryRegistry registry = new InMemoryRegistry();
 
@@ -62,7 +71,7 @@
 
 		// Create the submodel descriptor
 		SubmodelDescriptor submodelDescriptor = new SubmodelDescriptor(StubAASServlet.SMIDSHORT, StubAASServlet.SMURN,
-				"http://localhost:8080/basys.sdk/Testsuite/StubAAS/aas/submodels/" + StubAASServlet.SMIDSHORT);
+				"http://localhost:8080/basys.sdk/Testsuite/StubAAS/aas/submodels/" + StubAASServlet.SMIDSHORT + "/submodel");
 
 		// add submodel descriptor to the aas descriptor
 		aasDescriptor.addSubmodelDescriptor(submodelDescriptor);
@@ -71,7 +80,7 @@
 		registry.register(aasDescriptor);
 		
 		// Create manager using the directory stub an the HTTPConnectorProvider
-		manager = new ConnectedAssetAdministrationShellManager(registry, new HTTPConnectorProvider());
+		manager = new ConnectedAssetAdministrationShellManager(registry, new HTTPConnectorFactory());
 	}
 
 	/**
@@ -88,7 +97,7 @@
 		assertEquals(StubAASServlet.AASIDSHORT, shell.getIdShort());
 
 		// Retrieve submodels
-		Map<String, ISubModel> submodels = shell.getSubModels();
+		Map<String, ISubmodel> submodels = shell.getSubmodels();
 
 		// Check content of submodels
 		assertEquals(1, submodels.size());
@@ -101,9 +110,9 @@
 	 * @throws Exception
 	 */
 	@Test
-	public void testSubModel() throws Exception {
-		// Retrieve SubModel
-		ISubModel sm = manager.retrieveSubModel(StubAASServlet.AASURN, StubAASServlet.SMURN);
+	public void testSubmodel() throws Exception {
+		// Retrieve Submodel
+		ISubmodel sm = manager.retrieveSubmodel(StubAASServlet.AASURN, StubAASServlet.SMURN);
 
 		// Check id
 		assertEquals(StubAASServlet.SMIDSHORT, sm.getIdShort());
@@ -112,10 +121,9 @@
 		// - retrieve properties and operations
 
 		Map<String, IProperty> properties = sm.getProperties();
-		// 2 properties -> SMElementCollections don't count
 		assertEquals(3, properties.size());
 		IProperty prop = properties.get("integerProperty");
-		assertEquals(123, prop.get());
+		assertEquals(123, prop.getValue());
 
 		Map<String, IOperation> operations = sm.getOperations();
 		assertEquals(4, operations.size());
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/manager/TestConnectedAssetAdministrationShellManager.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/manager/TestConnectedAssetAdministrationShellManager.java
index b2fc2bb..5b9d9bf 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/manager/TestConnectedAssetAdministrationShellManager.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/manager/TestConnectedAssetAdministrationShellManager.java
@@ -1,25 +1,42 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.aas.manager;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.fail;
 
 import org.eclipse.basyx.aas.aggregator.AASAggregator;
 import org.eclipse.basyx.aas.aggregator.restapi.AASAggregatorProvider;
 import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
+import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.api.parts.asset.AssetKind;
 import org.eclipse.basyx.aas.metamodel.connected.ConnectedAssetAdministrationShell;
 import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
 import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
-import org.eclipse.basyx.aas.registration.api.IAASRegistryService;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
+import org.eclipse.basyx.aas.metamodel.map.parts.Asset;
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
 import org.eclipse.basyx.aas.registration.memory.InMemoryRegistry;
 import org.eclipse.basyx.aas.restapi.AASModelProvider;
-import org.eclipse.basyx.aas.restapi.VABMultiSubmodelProvider;
-import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
+import org.eclipse.basyx.aas.restapi.MultiSubmodelProvider;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
 import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
 import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
 import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
 import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
 import org.eclipse.basyx.testsuite.regression.vab.gateway.ConnectorProviderStub;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
 import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
 import org.junit.Before;
 import org.junit.Test;
@@ -33,7 +50,7 @@
 public class TestConnectedAssetAdministrationShellManager {
 	ConnectedAssetAdministrationShellManager manager;
 	ConnectorProviderStub connectorProvider;
-	IAASRegistryService registry;
+	IAASRegistry registry;
 	
 	/**
 	 * Create infrastructure
@@ -57,17 +74,16 @@
 		// Register AAS at directory
 		IIdentifier aasId = new Identifier(IdentifierType.CUSTOM, "aasId");
 		String aasIdShort = "aasName";
-		connectorProvider.addMapping("", new AASAggregatorProvider(new AASAggregator()));
-
-		// Create an AAS containing a reference to the created SubModel
-		AssetAdministrationShell aas = new AssetAdministrationShell();
-		aas.setIdentification(aasId);
-		aas.setIdShort(aasIdShort);
-		manager.createAAS(aas, aasId, "");
+		IModelProvider provider = new AASAggregatorProvider(new AASAggregator());
+		prepareConnectorProvider(provider);
+ 
+		// Create an AAS containing a reference to the created Submodel
+		AssetAdministrationShell aas = createTestAAS(aasId, aasIdShort);
+		manager.createAAS(aas, "/shells");
 
 		// Check descriptor for correct endpoint
 		String endpoint = registry.lookupAAS(aasId).getFirstEndpoint();
-		assertEquals("/aasList/" + aasId.getId() + "/aas", endpoint);
+		assertEquals(AASAggregatorProvider.PREFIX + "/" + aasId.getId() + "/aas", endpoint);
 
 		// Retrieve it
 		ConnectedAssetAdministrationShell connectedAAS = manager.retrieveAAS(aasId);
@@ -76,8 +92,9 @@
 		assertEquals(aasId.getIdType(), connectedAAS.getIdentification().getIdType());
 	}
 
+
 	@Test
-	public void testCreateSubModel() throws Exception {
+	public void testCreateSubmodel() throws Exception {
 		IIdentifier aasId = new Identifier(IdentifierType.CUSTOM, "aasId");
 		IIdentifier smId = new Identifier(IdentifierType.CUSTOM, "smId");
 		String smIdShort = "smName";
@@ -85,26 +102,26 @@
 		// Register AAS at directory
 		AASDescriptor desc = new AASDescriptor(aasId, "/aas");
 		registry.register(desc);
-		IModelProvider provider = new VABMultiSubmodelProvider(new AASModelProvider(new AssetAdministrationShell()));
+		IModelProvider provider = new MultiSubmodelProvider(new AASModelProvider(new AssetAdministrationShell()));
 		connectorProvider.addMapping("", provider);
 
 		// Create sub model
-		SubModel submodel = new SubModel();
+		Submodel submodel = new Submodel();
 		submodel.setIdShort(smIdShort);
 		submodel.setIdentification(smId.getIdType(), smId.getId());
 
 		// - Add example properties to sub model
 		Property prop1 = new Property(7);
 		prop1.setIdShort("prop1");
-		submodel.addSubModelElement(prop1);
+		submodel.addSubmodelElement(prop1);
 
 		Property prop2 = new Property("myStr");
 		prop2.setIdShort("prop2");
-		submodel.addSubModelElement(prop2);
+		submodel.addSubmodelElement(prop2);
 
 		// - Retrieve submodel using the SDK connector
-		manager.createSubModel(aasId, submodel);
-		ISubModel sm = manager.retrieveSubModel(aasId, smId);
+		manager.createSubmodel(aasId, submodel);
+		ISubmodel sm = manager.retrieveSubmodel(aasId, smId);
 
 		// - check id and properties
 		IProperty prop1Connected = sm.getProperties().get("prop1");
@@ -114,9 +131,123 @@
 		assertEquals(smId.getId(), sm.getIdentification().getId());
 		assertEquals(smId.getIdType(), sm.getIdentification().getIdType());
 		assertEquals("prop1", prop1Connected.getIdShort());
-		assertEquals(7, prop1Connected.get());
+		assertEquals(7, prop1Connected.getValue());
 		assertEquals("prop2", prop2Connected.getIdShort());
-		assertEquals("myStr", prop2Connected.get());
+		assertEquals("myStr", prop2Connected.getValue());
 	}
 
+	@Test
+	public void testDeleteSubmodel() {
+		IIdentifier aasId = new Identifier(IdentifierType.CUSTOM, "aasId");
+		String aasIdShort = "aasName";
+
+		IIdentifier smId = new Identifier(IdentifierType.CUSTOM, "smId");
+		String smIdShort = "smName";
+		
+		IModelProvider provider = new AASAggregatorProvider(new AASAggregator());
+		prepareConnectorProvider(provider);
+
+		AssetAdministrationShell aas = createTestAAS(aasId, aasIdShort);
+		manager.createAAS(aas, "/shells");
+
+		Submodel sm = new Submodel(smIdShort, smId);
+		manager.createSubmodel(aasId, sm);
+
+		// Assert everything was created correctly
+		IAssetAdministrationShell connectedAAS = manager.retrieveAAS(aasId);
+		ISubmodel connectedSm = connectedAAS.getSubmodels().get(sm.getIdShort());
+
+		assertEquals(sm.getIdShort(), connectedSm.getIdShort());
+
+		manager.deleteSubmodel(aasId, smId);
+		assertFalse(connectedAAS.getSubmodels().containsKey(smIdShort));
+	}
+
+	@Test
+	public void testDeleteAAS() {
+		IIdentifier aasId = new Identifier(IdentifierType.CUSTOM, "aasId");
+		String aasIdShort = "aasName";
+
+		IModelProvider provider = new AASAggregatorProvider(new AASAggregator());
+		prepareConnectorProvider(provider);
+
+		AssetAdministrationShell aas = createTestAAS(aasId, aasIdShort);
+		manager.createAAS(aas, "/shells");
+		manager.deleteAAS(aas.getIdentification());
+		try {
+			manager.retrieveAAS(aas.getIdentification());
+			fail();
+		} catch (ResourceNotFoundException e) {
+			// Expected
+		}
+	}
+
+	/**
+	 * Tries to retrieve a nonexistent AAS
+	 */
+	@Test
+	public void testRetrieveNonexistentAAS() {
+		IModelProvider provider = new AASAggregatorProvider(new AASAggregator());
+		prepareConnectorProvider(provider);
+		
+		IIdentifier nonexistentAASId = new Identifier(IdentifierType.CUSTOM, "nonexistentAAS");
+		
+		// Try to retrieve a nonexistent AAS
+		try {
+			manager.retrieveAAS(nonexistentAASId);
+			fail();
+		} catch (ResourceNotFoundException e) {
+		}
+	}
+	
+	/**
+	 * Tries to retrieve a nonexistent Submodel from a nonexistent AAS
+	 */
+	@Test
+	public void testRetrieveNonexistentSMFromNonexistentSM() {
+		IModelProvider provider = new AASAggregatorProvider(new AASAggregator());
+		prepareConnectorProvider(provider);
+		
+		IIdentifier nonexistentAASId = new Identifier(IdentifierType.CUSTOM, "nonexistentAAS");
+		IIdentifier nonexistentSMId = new Identifier(IdentifierType.CUSTOM, "nonexistentSM");
+		
+		// Try to retrieve a nonexistent Submodel from a nonexistent AAS
+		try {
+			manager.retrieveSubmodel(nonexistentAASId, nonexistentSMId);
+			fail();
+		} catch (ResourceNotFoundException e) {
+		}
+	}
+	
+	/**
+	 * Tries to retrieve a nonexistent Submodel from an existing AAS
+	 */
+	@Test
+	public void testRetrieveNonexistentSMFromExistentAAS() {
+		IModelProvider provider = new AASAggregatorProvider(new AASAggregator());
+		prepareConnectorProvider(provider);
+		
+		IIdentifier aasId = new Identifier(IdentifierType.CUSTOM, "aasId");
+		IIdentifier nonexistentSMId = new Identifier(IdentifierType.CUSTOM, "nonexistentSM");
+		
+		// Try to retrieve a nonexistent Submodel from an existing AAS
+		try {
+			manager.retrieveSubmodel(aasId, nonexistentSMId);
+			fail();
+		} catch (ResourceNotFoundException e) {
+		}
+	}
+	
+	/**
+	 * @param provider
+	 */
+	private void prepareConnectorProvider(IModelProvider provider) {
+		connectorProvider.addMapping("", new VABElementProxy("", provider));
+		connectorProvider.addMapping("shells", new VABElementProxy("shells", provider));
+	}
+
+	private AssetAdministrationShell createTestAAS(IIdentifier aasId, String aasIdShort) {
+		AssetAdministrationShell aas = new AssetAdministrationShell(aasIdShort, aasId, new Asset("assetIdShort", new ModelUrn("assetId"), AssetKind.INSTANCE));
+		return aas;
+	}
 }
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/AssetAdministrationShellSuite.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/AssetAdministrationShellSuite.java
index 6c1d626..d8aa3b3 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/AssetAdministrationShellSuite.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/AssetAdministrationShellSuite.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.aas.metamodel;
 
 import static org.junit.Assert.assertEquals;
@@ -5,12 +14,15 @@
 
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.List;
 
 import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.api.parts.asset.AssetKind;
 import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
-import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.CustomId;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
+import org.eclipse.basyx.aas.metamodel.map.parts.Asset;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
 import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
 import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
 import org.eclipse.basyx.submodel.metamodel.api.qualifier.IAdministrativeInformation;
@@ -19,12 +31,13 @@
 import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
 import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyType;
 import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
 import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
 import org.eclipse.basyx.submodel.metamodel.map.qualifier.AdministrativeInformation;
 import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
 import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
 import org.junit.Test;
 
 
@@ -71,11 +84,9 @@
 		 * setters, additional tests for setters are needed. Currently, this is tested
 		 * implicitly
 		 */
-		// Create an AAS containing a reference to the created SubModel
-		AssetAdministrationShell aas = new AssetAdministrationShell();
-		aas.setIdShort(AASIDSHORT);
-		aas.setIdentification(AASID);
-		aas.addSubModel(retrieveBaselineSM());
+		// Create an AAS containing a reference to the created Submodel
+		AssetAdministrationShell aas = new AssetAdministrationShell(AASIDSHORT, AASID, new Asset("assetIdShort", new CustomId("assetId"), AssetKind.INSTANCE));
+		aas.addSubmodel(retrieveBaselineSM());
 		aas.setAssetReference(EXPECTED_ASSETREF);
 		aas.setDerivedFrom(EXPECTED_DERIVEDFROMREF);
 		aas.setAdministration(EXPECTED_ADMINISTRATIVEINFORMATION);
@@ -89,21 +100,19 @@
 	 * 
 	 * @return
 	 */
-	protected static SubModel retrieveBaselineSM() {
+	protected static Submodel retrieveBaselineSM() {
 		/*
 		 * ! Caution: If the Submodel is constructed in any way that is not using the
 		 * setters, additional tests for setters are needed. Currently, this is tested
 		 * implicitly
 		 */
 
-		// Create a SubModel containing no operations and one property
+		// Create a Submodel containing no operations and one property
 		Property p = new Property(PROPVAL);
 		p.setIdShort(PROPID);
 
-		SubModel sm = new SubModel();
-		sm.addSubModelElement(p);
-		sm.setIdShort(SMIDSHORT);
-		sm.setIdentification(SMID.getIdType(), SMID.getId());
+		Submodel sm = new Submodel(SMIDSHORT, SMID);
+		sm.addSubmodelElement(p);
 
 		return sm;
 	}
@@ -125,7 +134,7 @@
 	}
 
 	/**
-	 * Tests retrieving the contained SubModels
+	 * Tests retrieving the contained Submodels
 	 * 
 	 * @throws Exception
 	 */
@@ -133,16 +142,16 @@
 	public void testGetSubmodel() throws Exception {
 		IAssetAdministrationShell shell = retrieveShell();
 
-		// Check if the number of SubModels is as expected
-		assertEquals(1, shell.getSubModels().size());
+		// Check if the number of Submodels is as expected
+		assertEquals(1, shell.getSubmodels().size());
 
-		// Check if the contained SubModel id is as expected
-		assertTrue(shell.getSubModels().containsKey(SMIDSHORT));
+		// Check if the contained Submodel id is as expected
+		assertTrue(shell.getSubmodels().containsKey(SMIDSHORT));
 
 		// Check if the submodel has been retrieved correctly
-		ISubModel sm = shell.getSubModels().get(SMIDSHORT);
+		ISubmodel sm = shell.getSubmodels().get(SMIDSHORT);
 		IProperty prop = sm.getProperties().get(PROPID);
-		assertEquals(PROPVAL, prop.get());
+		assertEquals(PROPVAL, prop.getValue());
 	}
 
 	/**
@@ -167,13 +176,14 @@
 		// Create a submodel
 		String smId = "newSubmodelId";
 		String testId = "smIdTest";
-		SubModel subModel = new SubModel(Collections.singletonList(new Property("testProperty")));
-		subModel.setIdentification(IdentifierType.CUSTOM, testId);
-		subModel.setIdShort(smId);
+		Submodel subModel = new Submodel(smId, new ModelUrn(testId));
+		Property prop = new Property("prop1", ValueType.String);
+		prop.setValue("testProperty");
+		subModel.addSubmodelElement(prop);
 		
 		//Retrieve the aas
 		IAssetAdministrationShell shell = retrieveShell();
-		shell.addSubModel(subModel);
+		shell.addSubmodel(subModel);
 		
 		// Create the expected reference for assertion
 		List<IKey> expected1Keys = new ArrayList<>();
@@ -184,7 +194,7 @@
 		List<IKey> expected2Keys = new ArrayList<>();
 		expected2Keys.add(new Key(KeyElements.ASSETADMINISTRATIONSHELL, true, AASID.getId(), AASID.getIdType()));
 
-		expected2Keys.add(new Key(KeyElements.SUBMODEL, true, testId, IdentifierType.CUSTOM));
+		expected2Keys.add(new Key(KeyElements.SUBMODEL, true, testId, IdentifierType.IRI));
 		Reference expected2 = new Reference(expected2Keys);
 
 		Collection<IReference> smReferences = shell.getSubmodelReferences();
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/connected/TestConnectedAssetAdministrationShell.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/connected/TestConnectedAssetAdministrationShell.java
index b9ee20b..6c2ffca 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/connected/TestConnectedAssetAdministrationShell.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/connected/TestConnectedAssetAdministrationShell.java
@@ -1,21 +1,36 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.aas.metamodel.connected;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+
 import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
 import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
 import org.eclipse.basyx.aas.metamodel.connected.ConnectedAssetAdministrationShell;
 import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
 import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
 import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
-import org.eclipse.basyx.aas.registration.api.IAASRegistryService;
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
 import org.eclipse.basyx.aas.registration.memory.InMemoryRegistry;
 import org.eclipse.basyx.aas.restapi.AASModelProvider;
-import org.eclipse.basyx.aas.restapi.VABMultiSubmodelProvider;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
-import org.eclipse.basyx.submodel.restapi.SubModelProvider;
+import org.eclipse.basyx.aas.restapi.MultiSubmodelProvider;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.restapi.SubmodelProvider;
 import org.eclipse.basyx.testsuite.regression.aas.metamodel.AssetAdministrationShellSuite;
 import org.eclipse.basyx.testsuite.regression.vab.gateway.ConnectorProviderStub;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
 import org.eclipse.basyx.vab.support.TypeDestroyer;
 import org.junit.Before;
+import org.junit.Test;
 
 /**
  * Tests the connected implementation of {@link IAssetAdministrationShell} based
@@ -30,20 +45,20 @@
 
 	@Before
 	public void build() throws Exception {
-		VABMultiSubmodelProvider provider = new VABMultiSubmodelProvider();
+		MultiSubmodelProvider provider = new MultiSubmodelProvider();
 		AssetAdministrationShell shell = retrieveBaselineShell();
 		provider.setAssetAdministrationShell(new AASModelProvider(AssetAdministrationShell.createAsFacade(TypeDestroyer.destroyType(shell))));
 
-		SubModel sm = retrieveBaselineSM();
+		Submodel sm = retrieveBaselineSM();
 		sm.setParent(shell.getReference());
-		provider.addSubmodel(SMIDSHORT, new SubModelProvider(SubModel.createAsFacade(TypeDestroyer.destroyType(sm))));
+		provider.addSubmodel(new SubmodelProvider(Submodel.createAsFacade(TypeDestroyer.destroyType(sm))));
 
 		// Create AAS registry
-		IAASRegistryService registry = new InMemoryRegistry();
+		IAASRegistry registry = new InMemoryRegistry();
 		// Create AAS Descriptor
 		AASDescriptor aasDescriptor = new AASDescriptor(AASID, "/aas");
 		// Create Submodel Descriptor
-		SubmodelDescriptor smDescriptor2 = new SubmodelDescriptor(SMIDSHORT, SMID, "/aas/submodels/" + SMIDSHORT);
+		SubmodelDescriptor smDescriptor2 = new SubmodelDescriptor(SMIDSHORT, SMID, "/aas/submodels/" + SMIDSHORT + "/submodel");
 		// Add Submodel descriptor to aas descriptor
 		aasDescriptor.addSubmodelDescriptor(smDescriptor2);
 
@@ -65,4 +80,24 @@
 	protected ConnectedAssetAdministrationShell retrieveShell() {
 		return connectedAAS;
 	}
+
+	@Test
+	public void testGetSpecificSubmodel() {
+		ISubmodel sm = retrieveShell().getSubmodel(SMID);
+		assertEquals(SMIDSHORT, sm.getIdShort());
+	}
+
+	@Test
+	public void testDeleteSubmodel() {
+		retrieveShell().removeSubmodel(SMID);
+		assertFalse(retrieveShell().getSubmodels().containsKey(SMIDSHORT));
+	}
+
+	@Test
+	public void testGetLocalCopy() {
+		AASModelProvider aasProvider = new AASModelProvider(retrieveBaselineShell());
+		ConnectedAssetAdministrationShell localCAAS = new ConnectedAssetAdministrationShell(new VABElementProxy("", aasProvider));
+
+		assertEquals(retrieveBaselineShell(), localCAAS.getLocalCopy());
+	}
 }
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/TestAasEnv.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/TestAasEnv.java
new file mode 100644
index 0000000..eb658bb
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/TestAasEnv.java
@@ -0,0 +1,115 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.aas.metamodel.map;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.api.parts.asset.AssetKind;
+import org.eclipse.basyx.aas.metamodel.map.AasEnv;
+import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.map.parts.Asset;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.eclipse.basyx.submodel.metamodel.map.modeltype.ModelType;
+import org.eclipse.basyx.submodel.metamodel.map.parts.ConceptDescription;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Identifiable;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
+import org.junit.Test;
+
+public class TestAasEnv {
+
+	
+	@Test
+	public void testAssetsGetSet() {
+		AasEnv env = new AasEnv();
+		Asset asset = new Asset();
+		asset.setIdShort("TestAasEnv");
+		env.setAssets(Arrays.asList(asset));
+		assertEquals(asset, env.getAssets().toArray()[0]);
+	}
+
+	@Test
+	public void testAssetAdministrationShellGetSet() {
+		AasEnv env = new AasEnv();
+		AssetAdministrationShell ass = new AssetAdministrationShell();
+		ass.setIdShort("TestAasEnv");
+		env.setAssetAdministrationShells(Arrays.asList(ass));
+		assertEquals(ass, env.getAssetAdministrationShells().toArray()[0]);
+	}
+	
+	@Test
+	public void testConceptDescriptionsGetSet() {
+		AasEnv env = new AasEnv();
+		ConceptDescription conceptDescriptions = new ConceptDescription();
+		conceptDescriptions.setIdShort("TestAasEnv");
+		env.setConceptDescriptions(Arrays.asList(conceptDescriptions));
+		assertEquals(conceptDescriptions, env.getConceptDescriptions().toArray()[0]);
+	}
+	
+	@Test
+	public void testSubmodelsGetSet() {
+		AasEnv env = new AasEnv();
+		Submodel submodels = new Submodel();
+		submodels.setIdShort("TestAasEnv");
+		env.setSubmodels(Arrays.asList(submodels));
+		assertEquals(submodels, env.getSubmodels().toArray()[0]);
+	}
+	
+	@Test
+	public void testCreateAsFacade() {
+		Map<String, Object> asset = new HashMap<>();
+		asset.put(ModelType.MODELTYPE, Asset.MODELTYPE);
+		asset.put(Referable.IDSHORT, "TestAsset");
+		asset.put(Asset.KIND, AssetKind.INSTANCE);
+		asset.put(Identifiable.IDENTIFICATION, new Identifier(IdentifierType.IRI, "testAssetIdShort"));
+		
+		Map<String, Object> assetAdministrationShell = new HashMap<>();
+		assetAdministrationShell.put(ModelType.MODELTYPE, AssetAdministrationShell.MODELTYPE);
+		assetAdministrationShell.put(Referable.IDSHORT, "TestAssetAdministrationShell");
+		assetAdministrationShell.put(AssetAdministrationShell.ASSET, asset);
+		assetAdministrationShell.put(Identifiable.IDENTIFICATION, new Identifier(IdentifierType.IRI, "testAASIdShort"));
+		
+		
+		Map<String, Object> submodel = new HashMap<>();
+		submodel.put(ModelType.MODELTYPE, Submodel.MODELTYPE);
+		submodel.put(Referable.IDSHORT, "TestSubmodel");
+		submodel.put(Submodel.SUBMODELELEMENT, new ArrayList<Object>());
+		submodel.put(Identifiable.IDENTIFICATION, new Identifier(IdentifierType.IRI, "testSubmodelIdShort"));
+		
+		Map<String, Object> conceptDescription = new HashMap<>();
+		conceptDescription.put(ModelType.MODELTYPE, ConceptDescription.MODELTYPE);
+		conceptDescription.put(Referable.IDSHORT, "TestConceptDescription");
+		conceptDescription.put(Identifiable.IDENTIFICATION, new Identifier(IdentifierType.IRI, "testConceptDesIdShort"));
+		
+		
+		Map<String, Object> aasEnvAsMap = new HashMap<>();
+		aasEnvAsMap.put(AasEnv.ASSETS, Arrays.asList(asset));
+		aasEnvAsMap.put(AasEnv.ASSETADMINISTRATIONSHELLS, Arrays.asList(assetAdministrationShell));
+		aasEnvAsMap.put(AasEnv.SUBMODELS, Arrays.asList(submodel));
+		aasEnvAsMap.put(AasEnv.CONCEPTDESCRIPTIONS, Arrays.asList(conceptDescription));
+		
+		AasEnv aasEnv = AasEnv.createAsFacade(aasEnvAsMap);
+		
+		Asset assetObj = (Asset)aasEnv.getAssets().toArray()[0];
+		assertEquals(assetObj.getIdShort(), asset.get(Referable.IDSHORT));
+		AssetAdministrationShell assetAdministrationShellObj = (AssetAdministrationShell)aasEnv.getAssetAdministrationShells().toArray()[0];
+		assertEquals(assetAdministrationShellObj.getIdShort(), assetAdministrationShell.get(Referable.IDSHORT));
+		Submodel submodelObj = (Submodel)aasEnv.getSubmodels().toArray()[0];
+		assertEquals(submodelObj.getIdShort(), submodel.get(Referable.IDSHORT));
+		ConceptDescription conceptDescriptionObj = (ConceptDescription)aasEnv.getConceptDescriptions().toArray()[0];
+		assertEquals(conceptDescriptionObj.getIdShort(), conceptDescription.get(Referable.IDSHORT));
+	}
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/TestAssetAdministrationShell.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/TestAssetAdministrationShell.java
index 80fb134..e663d24 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/TestAssetAdministrationShell.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/TestAssetAdministrationShell.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.aas.metamodel.map;
 
 import static org.junit.Assert.assertEquals;
@@ -6,7 +15,6 @@
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 
@@ -20,12 +28,14 @@
 import org.eclipse.basyx.submodel.metamodel.api.reference.IKey;
 import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
 import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
 import org.eclipse.basyx.submodel.metamodel.map.dataspecification.EmbeddedDataSpecification;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
 import org.eclipse.basyx.submodel.metamodel.map.parts.ConceptDescription;
 import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
 import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
 import org.eclipse.basyx.testsuite.regression.aas.metamodel.AssetAdministrationShellSuite;
 import org.junit.Before;
 import org.junit.Test;
@@ -63,17 +73,6 @@
 	}
 	
 	@Test
-	public void testSetEndpoint() {
-		String endpoint = "testEndpoint.com";
-		String endpointType = "http";
-		shell.setEndpoint(endpoint, endpointType);
-		List<HashMap<String, String>> endPoints = shell.getEndpoints();
-		HashMap<String, String> map = endPoints.iterator().next();
-		assertTrue(map.containsValue(endpoint));
-		assertTrue(map.containsValue(endpointType));
-	}
-	
-	@Test
 	public void testSetDataSpecificationReferences() {
 		Collection<IReference> refs = Collections.singleton(REFERENCE);
 		shell.setDataSpecificationReferences(refs);
@@ -111,6 +110,7 @@
 		shell.addConceptDescription(description);
 		Collection<IConceptDictionary> dictionaries = new HashSet<IConceptDictionary>();
 		ConceptDictionary dictionary = new ConceptDictionary();
+		dictionary.setIdShort("defaultConceptDictionary");
 		dictionary.addConceptDescription(description);
 		dictionaries.add(dictionary);
 		assertEquals(dictionaries, shell.getConceptDictionary());
@@ -119,19 +119,22 @@
 	@Test
 	public void testSetSubmodels() {
 		// Create submodels
-		SubModel subModel1 = new SubModel(Collections.singletonList(new Property("testProperty1")));
-		subModel1.setIdShort("newSubmodelId1");
-		subModel1.setIdentification(IdentifierType.CUSTOM, "smId1");
-		SubModel subModel2 = new SubModel(Collections.singletonList(new Property("testProperty2")));
-		subModel2.setIdShort("newSubmodelId2");
-		subModel2.setIdentification(IdentifierType.CUSTOM, "smId2");
+		Submodel subModel1 = new Submodel("newSubmodelId1", new Identifier(IdentifierType.CUSTOM, "smId1"));
+		Property prop1 = new Property("prop1Id", ValueType.String);
+		prop1.setValue("testProperty1");
+		subModel1.addSubmodelElement(prop1);
+
+		Submodel subModel2 = new Submodel("newSubmodelId2", new Identifier(IdentifierType.CUSTOM, "smId2"));
+		Property prop2 = new Property("prop2Id", ValueType.String);
+		prop2.setValue("testProperty2");
+		subModel2.addSubmodelElement(prop2);
 		
 		// create a collection of descriptors and add the above descriptors
-		Collection<SubModel> submodels = new ArrayList<SubModel>();
+		Collection<Submodel> submodels = new ArrayList<Submodel>();
 		submodels.add(subModel1);
 		submodels.add(subModel2);
 
-		shell.setSubModels(submodels);
+		shell.setSubmodels(submodels);
 
 		// expect references to be set according to the descriptors
 		Collection<IReference> smReferences = shell.getSubmodelReferences();
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/descriptor/TestAASDescriptor.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/descriptor/TestAASDescriptor.java
index 2720210..25782cc 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/descriptor/TestAASDescriptor.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/descriptor/TestAASDescriptor.java
@@ -1,11 +1,32 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.aas.metamodel.map.descriptor;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
 
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
 import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelDescriptor;
 import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
 import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
 import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Identifiable;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
+import org.eclipse.basyx.vab.exception.provider.MalformedRequestException;
+import org.junit.Before;
 import org.junit.Test;
 
 /**
@@ -15,24 +36,107 @@
  *
  */
 public class TestAASDescriptor {
+	
+	private Map<String, Object> map;
+	
+	@Before
+	public void initialize() {
+		map = new HashMap<String, Object>();
+		map.put(Referable.IDSHORT, "123");
+		map.put(Identifiable.IDENTIFICATION, new Identifier(IdentifierType.IRDI, "123"));
+		map.put(ModelDescriptor.ENDPOINTS, Arrays.asList(new HashMap<String, String>()));
+		map.put(AssetAdministrationShell.SUBMODELS, new HashSet<SubmodelDescriptor>());
+	}
 
 	/**
 	 * Tests retrieval of all registered submodel descriptors
 	 */
 	@Test
-	public void testGetAllSubModels() {
+	public void testGetAllSubmodels() {
 		// Setup descriptor and add one submodel descriptor
 		AASDescriptor descriptor = new AASDescriptor(new Identifier(IdentifierType.CUSTOM, "Test"), "http://a.b/c/aas");
 		descriptor.addSubmodelDescriptor(new SubmodelDescriptor("SM1", new Identifier(IdentifierType.CUSTOM, "SM1"), "http://a.b/c/aas/submodels/SM1"));
 
 		// Assert correct retrieval
-		assertEquals(1, descriptor.getSubModelDescriptors().size());
-		assertEquals("SM1", descriptor.getSubModelDescriptors().iterator().next().getIdentifier().getId());
+		assertEquals(1, descriptor.getSubmodelDescriptors().size());
+		assertEquals("SM1", descriptor.getSubmodelDescriptors().iterator().next().getIdentifier().getId());
 
 		// Add a second descriptor
 		descriptor.addSubmodelDescriptor(new SubmodelDescriptor("SM2", new Identifier(IdentifierType.CUSTOM, "SM2"), "http://a.b/c/aas/submodels/SM2"));
 
 		// Assert correct retrieval
-		assertEquals(2, descriptor.getSubModelDescriptors().size());
+		assertEquals(2, descriptor.getSubmodelDescriptors().size());
+	}
+	
+	@Test(expected = MalformedRequestException.class)
+	public void testValidateNoIdShort() {
+		map.remove(Referable.IDSHORT);
+		new AASDescriptor(map);
+	}
+	
+	@Test(expected = MalformedRequestException.class)
+	public void testValidateNullIdShort() {
+		map.put(Referable.IDSHORT, null);
+		new AASDescriptor(map);
+	}
+	
+	@Test(expected = MalformedRequestException.class)
+	public void testValidateWrongIdShort() {
+		map.put(Referable.IDSHORT, 0);
+		new AASDescriptor(map);
+	}
+	
+	@Test(expected = MalformedRequestException.class)
+	public void testValidateNoIdentification() {
+		map.remove(Identifiable.IDENTIFICATION);
+		new AASDescriptor(map);
+	}
+	
+	@Test(expected = MalformedRequestException.class)
+	public void testValidateNullIdentification() {
+		map.put(Identifiable.IDENTIFICATION, null);
+		new AASDescriptor(map);
+	}
+	
+	@Test(expected = MalformedRequestException.class)
+	public void testValidateWrongdentification() {
+		map.put(Identifiable.IDENTIFICATION, "testId");
+		new AASDescriptor(map);
+	}
+	
+	@Test(expected = MalformedRequestException.class)
+	public void testValidateNoEndpoints() {
+		map.remove(ModelDescriptor.ENDPOINTS);
+		new AASDescriptor(map);
+	}
+	
+	@Test(expected = MalformedRequestException.class)
+	public void testValidateNullEndpoints() {
+		map.put(ModelDescriptor.ENDPOINTS, null);
+		new AASDescriptor(map);
+	}
+	
+	@Test(expected = MalformedRequestException.class)
+	public void testValidateWrongEndpoints() {
+		map.put(ModelDescriptor.ENDPOINTS, "testEndpoint");
+		new AASDescriptor(map);
+	}
+	
+	@Test
+	public void testValidateNoSubmodels() {
+		map.remove(AssetAdministrationShell.SUBMODELS);
+		assertNotNull(new AASDescriptor(map).getSubmodelDescriptors());
+	}
+
+	@Test(expected = MalformedRequestException.class)
+	public void testValidateNullSubmodels() {
+		map.put(AssetAdministrationShell.SUBMODELS, null);
+		new AASDescriptor(map).getSubmodelDescriptors();
+	}
+
+	@Test(expected = MalformedRequestException.class)
+	public void testValidateWrongSubmodels() {
+		map.put(AssetAdministrationShell.SUBMODELS, "testSubmodel");
+		new AASDescriptor(map).getSubmodelDescriptors();
 	}
 }
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/descriptor/TestModelUrn.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/descriptor/TestModelUrn.java
index 5e31d2a..044ec7d 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/descriptor/TestModelUrn.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/descriptor/TestModelUrn.java
@@ -1,8 +1,20 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.aas.metamodel.map.descriptor;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 
 import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
 import org.junit.Test;
 
 /**
@@ -25,7 +37,7 @@
 	public void testConstructor2() {
 		String legalEntity = "testLegalEntity";
 		String subUnit = "testSubUnit";
-		String subModel = "testSubModel";
+		String subModel = "testSubmodel";
 		String version = "1.0";
 		String revision = "5";
 		String elementId = "testId";
@@ -34,6 +46,7 @@
 		ModelUrn modelUrn = new ModelUrn(legalEntity, subUnit, subModel, version, revision, elementId, elementInstance);
 		String appendedString = "urn:" + legalEntity + ":" + subUnit + ":" + subModel + ":" + version + ":" + revision + ":" + elementId + "#"+ elementInstance;
 		assertEquals(appendedString, modelUrn.getURN());
+		assertEquals(IdentifierType.IRI, modelUrn.getIdType());
 	}
 	
 	@Test
@@ -43,4 +56,10 @@
 		ModelUrn newModelUrn = modelUrn.append(suffix);
 		assertEquals(rawURN + suffix, newModelUrn.getURN());
 	}
+
+	@Test
+	public void testValidIdentifier() {
+		ModelUrn modelUrn = new ModelUrn(rawURN);
+		assertTrue(Identifier.isValid(modelUrn));
+	}
 }
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/descriptor/TestSubmodelDescriptor.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/descriptor/TestSubmodelDescriptor.java
index 55adcb4..e62df53 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/descriptor/TestSubmodelDescriptor.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/descriptor/TestSubmodelDescriptor.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.aas.metamodel.map.descriptor;
 
 import static org.junit.Assert.assertEquals;
@@ -9,7 +18,7 @@
 import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
 import org.eclipse.basyx.submodel.metamodel.api.qualifier.haskind.ModelingKind;
 import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
 import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
 import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasDataSpecification;
 import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasSemantics;
@@ -31,7 +40,7 @@
  */
 public class TestSubmodelDescriptor {
 	private static final IdentifierType ID_TYPE = IdentifierType.CUSTOM;
-	private static final String HTTP_ENDPOINT = "testEnd";
+	private static final String HTTP_ENDPOINT = "testEnd/submodel";
 	private static final String ID_SHORT_STRING = "testIdShort";
 	private static final Identifier IDENTIFIER = new Identifier(ID_TYPE, ID_SHORT_STRING);
 	
@@ -51,7 +60,7 @@
 		Formula formula = new Formula(Collections.singleton(new Reference(new Key(KeyElements.BLOB, true, "TestValue", IdentifierType.IRI))));
 		Qualifiable qualifiable = new Qualifiable(formula);
 		HasDataSpecification hasDataSpecification = new HasDataSpecification(new ArrayList<>(), Collections.singleton(reference));
-		SubModel subModel = new SubModel(hasSemantics, identifiable, qualifiable, hasDataSpecification, hasKind);
+		Submodel subModel = new Submodel(hasSemantics, identifiable, qualifiable, hasDataSpecification, hasKind);
 		
 		SubmodelDescriptor descriptor = new SubmodelDescriptor(subModel, HTTP_ENDPOINT);
 		assertEquals(HTTP_ENDPOINT, descriptor.getFirstEndpoint());
@@ -66,4 +75,4 @@
 		assertEquals(ID_SHORT_STRING, descriptor.getIdShort());
 		assertEquals(IDENTIFIER, descriptor.getIdentifier());
 	}
-}
\ No newline at end of file
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/parts/TestAsset.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/parts/TestAsset.java
index 54dcbde..4062b94 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/parts/TestAsset.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/parts/TestAsset.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.aas.metamodel.map.parts;
 
 import static org.junit.Assert.assertEquals;
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/parts/TestConceptDictionary.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/parts/TestConceptDictionary.java
index 51db72e..17737d7 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/parts/TestConceptDictionary.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/parts/TestConceptDictionary.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.aas.metamodel.map.parts;
 
 import static org.junit.Assert.assertEquals;
@@ -39,7 +48,8 @@
 	public void buildConceptDictionary() {
 		List<IReference> refs = new ArrayList<>();
 		refs.add(REFERENCE);
-		dictionary = new ConceptDictionary(refs);
+		dictionary = new ConceptDictionary("testIdShort");
+		dictionary.setConceptDescriptionReferences(refs);
 	}
 	
 	@Test
@@ -86,9 +96,9 @@
 	
 	@Test
 	public void testSetConceptDescriptions() {
-		ConceptDescription description1 = new ConceptDescription();
+		ConceptDescription description1 = new ConceptDescription("testIdShort1", new Identifier(IdentifierType.IRDI, "testIdShort1"));
 		description1.setCategory("cat1");
-		ConceptDescription description2 = new ConceptDescription();
+		ConceptDescription description2 = new ConceptDescription("testIdShort2", new Identifier(IdentifierType.IRDI, "testIdShort2"));
 		description2.setCategory("cat2");
 		Collection<IConceptDescription> descriptions = new ArrayList<IConceptDescription>();
 		descriptions.add(description1);
@@ -101,8 +111,7 @@
 	public void testAddConceptDescription() {
 		IdentifierType idType = IdentifierType.IRI;
 		String id = "testId";
-		ConceptDescription description = new ConceptDescription();
-		description.setIdentification(idType, id);
+		ConceptDescription description = new ConceptDescription("testIdShort", new Identifier(idType, id));
 		description.setCategory("testCategory");
 		dictionary.addConceptDescription(description);
 		assertEquals(Collections.singletonList(description), dictionary.getConceptDescriptions());
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/parts/TestView.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/parts/TestView.java
index 669472a..eb5fd09 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/parts/TestView.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/parts/TestView.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.aas.metamodel.map.parts;
 
 import static org.junit.Assert.assertEquals;
@@ -34,7 +43,8 @@
 	
 	@Before
 	public void buildConceptDictionary() {
-		view = new View(Collections.singleton(REFERENCE));
+		view = new View("testIdShort");
+		view.setContainedElement(Collections.singleton(REFERENCE));
 		references = new HashSet<IReference>();
 		references.add(REFERENCE);
 		references.add(REFERENCE2);
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/policypoints/TestAccessControlPolicyPoints.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/policypoints/TestAccessControlPolicyPoints.java
index a7bebae..ef52a64 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/policypoints/TestAccessControlPolicyPoints.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/policypoints/TestAccessControlPolicyPoints.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.aas.metamodel.map.policypoints;
 
 import static org.junit.Assert.assertEquals;
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/security/TestSecurity.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/security/TestSecurity.java
index e116091..d83bf01 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/security/TestSecurity.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/security/TestSecurity.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.aas.metamodel.map.security;
 
 import static org.junit.Assert.assertEquals;
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/TestRegistryProviderSuite.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/TestRegistryProviderSuite.java
index 7829405..57e3a43 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/TestRegistryProviderSuite.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/TestRegistryProviderSuite.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.aas.registration;
 
 import static org.junit.Assert.assertEquals;
@@ -12,7 +21,7 @@
 import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
 import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
 import org.eclipse.basyx.aas.metamodel.map.parts.Asset;
-import org.eclipse.basyx.aas.registration.api.IAASRegistryService;
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
 import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
 import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
 import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
@@ -32,7 +41,7 @@
  */
 public abstract class TestRegistryProviderSuite {
 	// The registry proxy that is used to access the sql servlet
-	protected final IAASRegistryService proxy = getRegistryService();
+	protected final IAASRegistry proxy = getRegistryService();
 
 	// Ids, shortIds and endpoints for registered AAS and submodel
 	protected IIdentifier aasId1 = new ModelUrn("urn:de.FHG:devices.es.iese/test:aas:1.0:1:registryAAS#001");
@@ -45,15 +54,15 @@
 	protected String smIdShort2 = "smIdShort2";
 	protected String aasEndpoint1 = "http://www.registrytest.de/aas01/aas";
 	protected String aasEndpoint2 = "http://www.registrytest.de/aas02/aas";
-	protected String smEndpoint1 = "http://www.registrytest.de/aas01/aas/submodels/" + smIdShort1;
-	protected String smEndpoint2 = "http://www.registrytest.de/aas01/aas/submodels/" + smIdShort2;
+	protected String smEndpoint1 = "http://www.registrytest.de/aas01/aas/submodels/" + smIdShort1 + "/submodel";
+	protected String smEndpoint2 = "http://www.registrytest.de/aas01/aas/submodels/" + smIdShort2 + "/submodel";
 	protected Asset asset1;
 	protected Asset asset2;
 	/**
 	 * Getter for the tested registry provider. Tests for actual registry provider
 	 * have to realize this method.
 	 */
-	protected abstract IAASRegistryService getRegistryService();
+	protected abstract IAASRegistry getRegistryService();
 
 	/**
 	 * Before each test, clean entries are created in the registry using a proxy
@@ -63,8 +72,10 @@
 		// Create assets
 		asset1 = new Asset(new Reference(new Identifier(IdentifierType.CUSTOM, "asset001"), KeyElements.ASSET, false));
 		asset1.setIdentification(IdentifierType.CUSTOM, "asset001");
+		asset1.setIdShort("asset001");
 		asset2 = new Asset(new Reference(new Identifier(IdentifierType.CUSTOM, "asset002"), KeyElements.ASSET, false));
 		asset2.setIdentification(IdentifierType.CUSTOM, "asset002");
+		asset2.setIdShort("asset002");
 		// Create descriptors for AAS and submodels
 		AASDescriptor aasDesc1 = new AASDescriptor(aasIdShort1, aasId1, asset1, aasEndpoint1);
 		aasDesc1.addSubmodelDescriptor(new SubmodelDescriptor(smIdShort1, smId1, smEndpoint1));
@@ -125,7 +136,7 @@
 	 * Checks, if the given descriptor is valid. Should contain the values of the first descriptor
 	 * as given by the test setup
 	 */
-	private void validateDescriptor1(AASDescriptor descriptor) {
+	protected void validateDescriptor1(AASDescriptor descriptor) {
 		assertEquals(aasId1.getId(), descriptor.getIdentifier().getId());
 		assertEquals(aasId1.getIdType(), descriptor.getIdentifier().getIdType());
 		IAsset asset = descriptor.getAsset();
@@ -133,7 +144,7 @@
 		assertEquals(aasEndpoint1, descriptor.getFirstEndpoint());
 
 		// Check, if the SM descriptor in the AASDescriptor is correct
-		SubmodelDescriptor smDescriptor = descriptor.getSubModelDescriptorFromIdentifierId(smId1.getId());
+		SubmodelDescriptor smDescriptor = descriptor.getSubmodelDescriptorFromIdentifierId(smId1.getId());
 		assertEquals(smId1.getId(), smDescriptor.getIdentifier().getId());
 		assertEquals(smId1.getIdType(), smDescriptor.getIdentifier().getIdType());
 		assertEquals(smIdShort1, smDescriptor.get(Referable.IDSHORT));
@@ -144,7 +155,7 @@
 	 * Checks, if the given descriptor is valid. Should contain the values of the second descriptor
 	 * as given by the test setup
 	 */
-	private void validateDescriptor2(AASDescriptor descriptor) {
+	protected void validateDescriptor2(AASDescriptor descriptor) {
 		assertEquals(aasId2.getId(), descriptor.getIdentifier().getId());
 		assertEquals(aasId2.getIdType(), descriptor.getIdentifier().getIdType());
 		IAsset asset = descriptor.getAsset();
@@ -152,6 +163,42 @@
 		assertEquals(aasEndpoint2, descriptor.getFirstEndpoint());
 	}
 
+	@Test
+	public void testDeleteWithAssetExtension() {
+		// After the setup, both AAS should have been inserted to the registry
+		assertNotNull(proxy.lookupAAS(aasId1));
+		assertNotNull(proxy.lookupAAS(aasId2));
+
+		proxy.delete(aasId2);
+
+		// After aas2 has been deleted, only aas1 should be registered
+		assertNotNull(proxy.lookupAAS(asset1.getIdentification()));
+
+		// Reference of asset-id to the AAS descriptor should also to deleted
+		try {
+			proxy.lookupAAS(asset2.getIdentification());
+			fail();
+		} catch (ResourceNotFoundException e) {
+			// expected
+		}
+
+		proxy.delete(aasId1);
+
+		// Reference of both asset-ids to the AAS descriptors should also to deleted
+		try {
+			proxy.lookupAAS(asset1.getIdentification());
+			fail();
+		} catch (ResourceNotFoundException e) {
+			// expected
+		}
+		try {
+			proxy.lookupAAS(asset2.getIdentification());
+			fail();
+		} catch (ResourceNotFoundException e) {
+			// expected
+		}
+	}
+
 	/**
 	 * Tests deletion for aas entries
 	 */
@@ -165,7 +212,6 @@
 		
 		// After aas2 has been deleted, only aas1 should be registered
 		assertNotNull(proxy.lookupAAS(aasId1));
-		assertNotNull(proxy.lookupAAS(asset1.getIdentification()));
 		try {
 			proxy.lookupAAS(aasId2);
 			fail();
@@ -173,14 +219,6 @@
 			// expected
 		}
 
-		// Reference of asset-id to the AAS descriptor should also to deleted
-		try {
-			proxy.lookupAAS(asset2.getIdentification());
-			fail();
-		} catch (ResourceNotFoundException e) {
-			// expected
-		}
-
 		proxy.delete(aasId1);
 
 		// After aas1 has been deleted, both should not be registered any more
@@ -196,16 +234,27 @@
 		} catch (ResourceNotFoundException e) {
 			// expected
 		}
+	}
 
-		// Reference of both asset-ids to the AAS descriptors should also to deleted
+	/**
+	 * Tests deletion for aas entries
+	 */
+	@Test
+	public void testDeleteByAssetIdCall() {
+		proxy.delete(asset1.getIdentification());
+
+		// After aas1 has been deleted, only aas2 should be registered
+		assertNotNull(proxy.lookupAAS(aasId2));
+		assertNotNull(proxy.lookupAAS(asset2.getIdentification()));
 		try {
-			proxy.lookupAAS(asset1.getIdentification());
+			proxy.lookupAAS(aasId1);
 			fail();
 		} catch (ResourceNotFoundException e) {
 			// expected
 		}
+
 		try {
-			proxy.lookupAAS(asset2.getIdentification());
+			proxy.lookupAAS(asset1.getIdentification());
 			fail();
 		} catch (ResourceNotFoundException e) {
 			// expected
@@ -214,12 +263,12 @@
 
 	@Test(expected = ResourceNotFoundException.class)
 	public void testDeleteNotExistingSubmodelFromNotExistingAAS() {
-		proxy.delete(new Identifier(IdentifierType.CUSTOM, "nonExistent"), "nonExistentSubModelId");
+		proxy.delete(new Identifier(IdentifierType.CUSTOM, "nonExistent"), new Identifier(IdentifierType.CUSTOM, "nonExistentSubmodelId"));
 	}
 
 	@Test(expected = ResourceNotFoundException.class)
-	public void testDeleteNotExistingSubModel() {
-		proxy.delete(aasId1, "nonExistentSubModelId");
+	public void testDeleteNotExistingSubmodel() {
+		proxy.delete(aasId1, new Identifier(IdentifierType.CUSTOM, "nonExistentSubmodelId"));
 	}
 
 	@Test(expected = ResourceNotFoundException.class)
@@ -227,12 +276,25 @@
 		proxy.delete(new Identifier(IdentifierType.CUSTOM, "nonExistent"));
 	}
 
+	@Test
+	public void testRetrieveSubmodelDescriptors() {
+		List<SubmodelDescriptor> descs = proxy.lookupSubmodels(aasId1);
+		assertEquals(1, descs.size());
+		assertEquals(smIdShort1, descs.get(0).getIdShort());
+	}
+
+	@Test
+	public void testRetrieveSpecificSubmodelDescriptor() {
+		SubmodelDescriptor desc = proxy.lookupSubmodel(aasId1, smId1);
+		assertEquals(smIdShort1, desc.getIdShort());
+	}
+
 	/**
 	 * Tests overwriting the descriptor of an AAS
 	 */
 	@Test
 	public void testOverwritingAASDescriptor() {
-		AASDescriptor aasDesc2 = new AASDescriptor(aasIdShort2, aasId2, asset2, "TestEndpoint");
+		AASDescriptor aasDesc2 = new AASDescriptor(aasIdShort2, aasId2, asset2, "http://testendpoint2/");
 		proxy.register(aasDesc2);
 		AASDescriptor retrieved = proxy.lookupAAS(aasId2);
 		assertEquals(aasDesc2.getFirstEndpoint(), retrieved.getFirstEndpoint());
@@ -252,17 +314,22 @@
 		assertEquals(smDesc, aasDesc.getSubmodelDescriptorFromIdShort(smIdShort2));
 
 		// Test overwriting an SM descriptor
-		SubmodelDescriptor smDescNew = new SubmodelDescriptor(smIdShort2, smId2, "TestEndpoint");
+		SubmodelDescriptor smDescNew = new SubmodelDescriptor(smIdShort2, smId2, "http://testendpoint2/submodel/");
 		proxy.register(aasId1, smDescNew);
 		AASDescriptor aasDescNew = proxy.lookupAAS(aasId1);
 		assertEquals(smDescNew.getFirstEndpoint(), aasDescNew.getSubmodelDescriptorFromIdShort(smIdShort2).getFirstEndpoint());
 
 		// Remove Submodel
-		proxy.delete(aasId1, smIdShort2);
+		proxy.delete(aasId1, smId2);
 
 		// Ensure that the submodel was correctly removed
 		aasDesc = proxy.lookupAAS(aasId1);
 		assertNotNull(aasDesc.getSubmodelDescriptorFromIdShort(smIdShort1));
 		assertNull(aasDesc.getSubmodelDescriptorFromIdShort(smIdShort2));
 	}
+	
+	@Test(expected = ResourceNotFoundException.class)
+	public void testRegisterSubmodelToNotExistingAAS() {
+		proxy.register(new Identifier(IdentifierType.CUSTOM, "nonExistent"), new SubmodelDescriptor(smIdShort1, smId1, smEndpoint1));
+	}
 }
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/memory/TestMapRegistry.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/memory/TestMapRegistry.java
index 9cb8f07..3ef1f3e 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/memory/TestMapRegistry.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/memory/TestMapRegistry.java
@@ -1,12 +1,21 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.aas.registration.memory;
 
-import org.eclipse.basyx.aas.registration.api.IAASRegistryService;
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
 import org.eclipse.basyx.aas.registration.memory.InMemoryRegistry;
-import org.eclipse.basyx.aas.registration.memory.MapRegistry;
+import org.eclipse.basyx.aas.registration.memory.MapRegistryHandler;
 import org.eclipse.basyx.testsuite.regression.aas.registration.TestRegistryProviderSuite;
 
 /**
- * Tests functionalities of {@link MapRegistry} for their correctness
+ * Tests functionalities of {@link MapRegistryHandler} for their correctness
  * Includes test cases for exceptions
  * 
  * @author haque
@@ -15,7 +24,7 @@
 public class TestMapRegistry extends TestRegistryProviderSuite {
 
 	@Override
-	protected IAASRegistryService getRegistryService() {
+	protected IAASRegistry getRegistryService() {
 		return new InMemoryRegistry();
 	}
 }
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/restapi/AASRegistryServlet.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/restapi/AASRegistryServlet.java
new file mode 100644
index 0000000..495db3f
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/restapi/AASRegistryServlet.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.aas.registration.restapi;
+
+import org.eclipse.basyx.aas.registration.memory.InMemoryRegistry;
+import org.eclipse.basyx.aas.registration.restapi.AASRegistryModelProvider;
+import org.eclipse.basyx.vab.protocol.http.server.VABHTTPInterface;
+
+/**
+ * A registry servlet based on an InMemory Registry. The servlet therefore provides an implementation
+ * for the IAASRegistryService interface without a permanent storage capability.
+ * 
+ * @author espen
+ */
+public class AASRegistryServlet extends VABHTTPInterface<AASRegistryModelProvider> {
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * Constructor with ModelProvider based on an InMemoryRegistry
+	 */
+	public AASRegistryServlet() {
+		super(new AASRegistryModelProvider(new InMemoryRegistry()));
+
+	}
+}
+
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/restapi/DirectoryProviderServlet.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/restapi/DirectoryProviderServlet.java
deleted file mode 100644
index b8ac0ec..0000000
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/restapi/DirectoryProviderServlet.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package org.eclipse.basyx.testsuite.regression.aas.registration.restapi;
-
-import org.eclipse.basyx.aas.registration.memory.InMemoryRegistry;
-import org.eclipse.basyx.aas.registration.restapi.DirectoryModelProvider;
-import org.eclipse.basyx.vab.protocol.http.server.VABHTTPInterface;
-
-/**
- * A registry servlet based on an InMemory Registry. The servlet therefore provides an implementation
- * for the IAASRegistryService interface without a permanent storage capability.
- * 
- * @author espen
- */
-public class DirectoryProviderServlet extends VABHTTPInterface<DirectoryModelProvider> {
-	private static final long serialVersionUID = 1L;
-
-	/**
-	 * Constructor with ModelProvider based on an InMemoryRegistry
-	 */
-	public DirectoryProviderServlet() {
-		super(new DirectoryModelProvider(new InMemoryRegistry()));
-
-	}
-}
-
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/restapi/TestDirectoryModelProvider.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/restapi/TestDirectoryModelProvider.java
index a4b001b..868b8b5 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/restapi/TestDirectoryModelProvider.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/restapi/TestDirectoryModelProvider.java
@@ -1,8 +1,17 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.aas.registration.restapi;
 
-import org.eclipse.basyx.aas.registration.api.IAASRegistryService;
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
 import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
-import org.eclipse.basyx.aas.registration.restapi.DirectoryModelProvider;
+import org.eclipse.basyx.aas.registration.restapi.AASRegistryModelProvider;
 import org.eclipse.basyx.testsuite.regression.aas.registration.TestRegistryProviderSuite;
 
 /**
@@ -14,8 +23,8 @@
  */
 public class TestDirectoryModelProvider extends TestRegistryProviderSuite {
 	@Override
-	protected IAASRegistryService getRegistryService() {
-		DirectoryModelProvider provider = new DirectoryModelProvider();
+	protected IAASRegistry getRegistryService() {
+		AASRegistryModelProvider provider = new AASRegistryModelProvider();
 		return new AASRegistryProxy(provider);
 	}
 
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/restapi/TestDirectoryModelProviderServlet.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/restapi/TestDirectoryModelProviderServlet.java
index 6bb8403..0fbc2fc 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/restapi/TestDirectoryModelProviderServlet.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/restapi/TestDirectoryModelProviderServlet.java
@@ -1,6 +1,15 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.aas.registration.restapi;
 
-import org.eclipse.basyx.aas.registration.api.IAASRegistryService;
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
 import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
 import org.eclipse.basyx.testsuite.regression.aas.registration.TestRegistryProviderSuite;
 import org.eclipse.basyx.testsuite.regression.vab.protocol.http.AASHTTPServerResource;
@@ -21,10 +30,10 @@
 	@Rule
 	public AASHTTPServerResource res = new AASHTTPServerResource(
 			new BaSyxContext("/basys.sdk", System.getProperty("java.io.tmpdir"))
-					.addServletMapping("/Testsuite/directory/*", new DirectoryProviderServlet()));
+					.addServletMapping("/Testsuite/directory/*", new AASRegistryServlet()));
 
 	@Override
-	protected IAASRegistryService getRegistryService() {
+	protected IAASRegistry getRegistryService() {
 		return new AASRegistryProxy("http://localhost:8080/basys.sdk/Testsuite/directory");
 	}
 
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/restapi/MultiAASProviderTest.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/restapi/MultiAASProviderTest.java
deleted file mode 100644
index a37c034..0000000
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/restapi/MultiAASProviderTest.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/**
- * 
- */
-package org.eclipse.basyx.testsuite.regression.aas.restapi;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.fail;
-
-import java.util.Map;
-
-import org.eclipse.basyx.aas.restapi.MultiAASProvider;
-import org.eclipse.basyx.aas.restapi.VABMultiSubmodelProvider;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.submodel.restapi.SubModelProvider;
-import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
-import org.eclipse.basyx.testsuite.regression.submodel.restapi.SimpleAASSubmodel;
-import org.eclipse.basyx.testsuite.regression.vab.manager.VABConnectionManagerStub;
-import org.eclipse.basyx.vab.exception.provider.ProviderException;
-import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
-import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * Tests the capability to multiplex of a VABMultiAASProvider
- * 
- * @author espen
- *
- */
-public class MultiAASProviderTest {
-	VABElementProxy proxy;
-	MultiAASProvider provider;
-
-	@Before
-	public void build() {
-		VABConnectionManagerStub stub = new VABConnectionManagerStub();
-		String urn = "urn:fhg:es.iese:aas:1:1:submodel";
-		VABMultiSubmodelProvider aasProvider = new VABMultiSubmodelProvider();
-		aasProvider.addSubmodel("SimpleAASSubmodel", new SubModelProvider(new SimpleAASSubmodel()));
-		provider = new MultiAASProvider();
-		provider.addMultiSubmodelProvider("a1", aasProvider);
-		stub.addProvider(urn, "", provider);
-		proxy = stub.connectToVABElement(urn);
-	}
-
-	@Test
-	public void clearTest() {
-		provider.clear();
-		Object result = proxy.getModelPropertyValue("a1/aas/submodels/SimpleAASSubmodel/");
-		assertNull(result);
-	}
-
-	@SuppressWarnings("unchecked")
-	@Test
-	public void getTest() {
-		// test reading from a valid aas
-		Map<String, Object> result = (Map<String, Object>) proxy
-				.getModelPropertyValue("a1/aas/submodels/SimpleAASSubmodel/" + SubmodelElementProvider.PROPERTIES + "/integerProperty/value");
-		assertEquals(123, result.get(Property.VALUE));
-
-		// test reading from an invalid aas
-		assertNull(proxy.getModelPropertyValue("A1/aas/submodels/SimpleAASSubmodel/"));
-	}
-
-	@SuppressWarnings("unchecked")
-	@Test
-	public void setTest() {
-		// test setting in a valid aas
-		proxy.setModelPropertyValue("a1/aas/submodels/SimpleAASSubmodel/" + SubmodelElementProvider.PROPERTIES + "/integerProperty/value", 100);
-
-		// test setting in an invalid aas
-		proxy.setModelPropertyValue("A1/aas/submodels/SimpleAASSubmodel/" + SubmodelElementProvider.PROPERTIES + "/integerProperty/value", 200);
-
-		// retrieving property
-		Map<String, Object> result = (Map<String, Object>) proxy
-				.getModelPropertyValue("a1/aas/submodels/SimpleAASSubmodel/" + SubmodelElementProvider.PROPERTIES + "/integerProperty/value");
-		assertEquals(100, result.get(Property.VALUE));
-	}
-
-	@SuppressWarnings("unchecked")
-	@Test
-	public void removeTest() {
-		// test deleting from an invalid aas
-		proxy.deleteValue("A1/aas/submodels/SimpleAASSubmodel/" + SubmodelElementProvider.PROPERTIES + "/integerProperty/value");
-		Map<String, Object> result = (Map<String, Object>) proxy
-				.getModelPropertyValue("a1/aas/submodels/SimpleAASSubmodel/" + SubmodelElementProvider.PROPERTIES + "/integerProperty/value");
-		assertEquals(123, result.get(Property.VALUE));
-
-		// test deleting from a valid aas
-		proxy.deleteValue("a1/aas/submodels/SimpleAASSubmodel/" + SubmodelElementProvider.PROPERTIES + "/integerProperty");
-		try {
-			proxy.getModelPropertyValue("a1/aas/submodels/SimpleAASSubmodel/" + SubmodelElementProvider.PROPERTIES + "/integerProperty/");
-			fail();
-		} catch (ResourceNotFoundException e) {
-		}
-	}
-
-	@Test
-	public void invokeExceptionTest() {
-		// Invoke exception1
-		try {
-			proxy.invokeOperation("a1/aas/submodels/SimpleAASSubmodel/operations/exception1");
-			fail();
-		} catch (ProviderException e) {
-			assertEquals(NullPointerException.class, e.getCause().getClass());
-		}
-		// Invoke exception2
-		try {
-			proxy.invokeOperation("a1/aas/submodels/SimpleAASSubmodel/operations/exception2", "prop1");
-			fail();
-		} catch (ProviderException e) {
-			assertEquals("Exception description", e.getMessage());
-		}
-	}
-
-	@Test
-	public void invokeTest() {
-		// test invoking from an invalid aas
-		assertNull(proxy.invokeOperation("A1/aas/submodels/SimpleAASSubmodel/operations/complex", 10, 3));
-
-		// test invoking with return value
-		assertEquals(7, proxy.invokeOperation("a1/aas/submodels/SimpleAASSubmodel/operations/complex", 10, 3));
-		assertEquals(true, proxy.invokeOperation("a1/aas/submodels/SimpleAASSubmodel/operations/simple"));
-	}
-}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/restapi/MultiSubmodelProviderRemoteInvocationTest.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/restapi/MultiSubmodelProviderRemoteInvocationTest.java
new file mode 100644
index 0000000..73ca6af
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/restapi/MultiSubmodelProviderRemoteInvocationTest.java
@@ -0,0 +1,224 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.aas.restapi;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
+import org.eclipse.basyx.aas.registration.memory.InMemoryRegistry;
+import org.eclipse.basyx.aas.restapi.AASModelProvider;
+import org.eclipse.basyx.aas.restapi.MultiSubmodelProvider;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation;
+import org.eclipse.basyx.submodel.restapi.SubmodelProvider;
+import org.eclipse.basyx.testsuite.regression.submodel.restapi.SimpleAASSubmodel;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.eclipse.basyx.vab.modelprovider.VABPathTools;
+import org.eclipse.basyx.vab.protocol.basyx.connector.BaSyxConnectorFactory;
+import org.eclipse.basyx.vab.protocol.basyx.server.BaSyxTCPServer;
+import org.eclipse.basyx.vab.service.api.BaSyxService;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests the capability remote submodel invocation from registry 
+ * in VABMultiSubmodelProvider
+ * 
+ * @author haque
+ */
+public class MultiSubmodelProviderRemoteInvocationTest {
+	private static final IIdentifier AASID1 = new ModelUrn("aas");
+	private static final String AASIDSHORT1 = "aasIdShort1";
+
+	private static final IIdentifier REMOTESMID = new ModelUrn("remoteSm");
+	private static final String REMOTESMIDSHORT = "remoteSmIdShort";
+
+	private static final IIdentifier LOCALSMID = new ModelUrn("localSm");
+	private static final String LOCALSMIDSHORT = "localSmIdShort";
+
+	private static final String REMOTEPATH = "/aas/submodels/" + REMOTESMIDSHORT + "/" + SubmodelProvider.SUBMODEL;
+
+	private List<BaSyxService> services = new ArrayList<>();
+
+	private MultiSubmodelProvider provider;
+	
+	// Creating a new AAS Registry
+	private IAASRegistry registry = new InMemoryRegistry();
+
+	@Before
+	public void init() {
+		
+		
+		// Create descriptors for AAS and submodels
+		String aasEndpoint = "basyx://localhost:8000/aas";
+		String remoteSmEndpoint = "basyx://localhost:8001/submodel";
+		String localSmEndpoint = "basyx://localhost:8000/aas/submodels/" + LOCALSMIDSHORT;
+
+		AASDescriptor aasDesc = new AASDescriptor(AASIDSHORT1, AASID1, aasEndpoint);
+		aasDesc.addSubmodelDescriptor(new SubmodelDescriptor(REMOTESMIDSHORT, REMOTESMID, remoteSmEndpoint));
+		aasDesc.addSubmodelDescriptor(new SubmodelDescriptor(LOCALSMIDSHORT, LOCALSMID, localSmEndpoint));
+
+		// Register Asset Administration Shells
+		registry.register(aasDesc);
+		
+
+		// Create a VABMultiSubmodelProvider using the registry and a http connector
+		provider = new MultiSubmodelProvider(registry, new BaSyxConnectorFactory());
+		
+		// Create and add an AAS to the provider with same id as the AAS in the registry
+		AssetAdministrationShell aas = new AssetAdministrationShell();
+		aas.setIdShort(AASIDSHORT1);
+		aas.setIdentification(AASID1);
+		provider.setAssetAdministrationShell(new AASModelProvider(aas));
+
+		// Create the local SM
+		Submodel localSM = new Submodel(LOCALSMIDSHORT, LOCALSMID);
+		provider.addSubmodel(new SubmodelProvider(localSM));
+
+		// Create the remote SM
+		Submodel remoteSm = new SimpleAASSubmodel(REMOTESMIDSHORT);
+		remoteSm.setIdentification(REMOTESMID.getIdType(), REMOTESMID.getId());
+
+		// Setup and start the BaSyx TCP servers
+		services.add(new BaSyxTCPServer<>(provider, 8000));
+		services.add(new BaSyxTCPServer<>(new SubmodelProvider(remoteSm), 8001));
+
+		services.forEach(b -> b.start());
+	}
+	
+	/**
+	 * Checks if GET is correctly forwarded by checking if the Id of the remote
+	 * submodel can be retrieved
+	 * 
+	 * @throws Exception
+	 */
+	@Test
+	public void testGetModelPropertyValue() throws Exception {
+		Submodel sm = getRemoteSubmodel();
+		assertEquals(sm.getIdentification().getId(), REMOTESMID.getId());
+	}
+	
+	/**
+	 * Checks if a call to "/aas/submodels" correctly includes the remote submodels
+	 */
+	@SuppressWarnings("unchecked")
+	@Test
+	public void testGetAllSubmodels() {
+		Collection<Map<String, Object>> collection = (Collection<Map<String, Object>>) provider.getValue("/aas/submodels");
+		Collection<String> smIdShorts = collection.stream().map(m -> Submodel.createAsFacade(m)).map(sm -> sm.getIdShort()).collect(Collectors.toList());
+		assertTrue(smIdShorts.contains(REMOTESMIDSHORT));
+		assertTrue(smIdShorts.contains(LOCALSMIDSHORT));
+		assertTrue(smIdShorts.size() == 2);
+	}
+	
+	/**
+	 * Tries to register a Submodel, not actually push it to the server and try to request all Submodels
+	 * This will result in an endless loop if not handled correctly
+	 */
+	@Test
+	public void testGetRegisteredButNotExistentSM() {
+		// Create a Descriptor for a Submodel (with a local Endpoint), that is not present on the server
+		SubmodelDescriptor smDescriptor = new SubmodelDescriptor("nonexist", new ModelUrn("nonexisting"), "basyx://localhost:8000/aas/submodels/nonexist");
+		
+		// Register this SubmodelDescriptor
+		registry.register(AASID1, smDescriptor);
+		
+		// Try to request all Submodels from the server
+		try {
+			provider.getValue("/aas/submodels");
+			fail();
+		} catch (ResourceNotFoundException e) {
+		}
+	}
+
+	/**
+	 * Checks if SET is correctly forwarded by checking if a property value of the
+	 * remote submodel can be changed
+	 * 
+	 * @throws Exception
+	 */
+	@Test
+	public void testSetModelPropertyValue() throws Exception {
+		int newVal = 0;
+		String path = VABPathTools.concatenatePaths(REMOTEPATH, Submodel.SUBMODELELEMENT, SimpleAASSubmodel.INTPROPIDSHORT, Property.VALUE);
+		provider.setValue(path, newVal);
+
+		Submodel sm = getRemoteSubmodel();
+		assertEquals(newVal, sm.getProperties().get(SimpleAASSubmodel.INTPROPIDSHORT).getValue());
+	}
+	
+	/**
+	 * Checks if CREATE is correctly forwarded by checking if a new property can be
+	 * created in the remote submodel
+	 * 
+	 * @throws Exception
+	 */
+	@Test
+	public void testCreateModelPropertyValue() throws Exception {
+		Property p = new Property(5);
+		String testPropIdShort = "testProperty";
+		p.setIdShort(testPropIdShort);
+
+		provider.setValue(REMOTEPATH + "/submodelElements/" + testPropIdShort, p);
+
+		assertTrue(getRemoteSubmodel().getProperties().containsKey(testPropIdShort));
+	}
+	
+	/**
+	 * Checks if DELETE is correctly forwarded by checking if a property can be
+	 * deleted in the remote submodel
+	 * 
+	 * @throws Exception
+	 */
+	@Test
+	public void testDeleteModelPropertyValue() throws Exception {
+		String path = VABPathTools.concatenatePaths(REMOTEPATH, Submodel.SUBMODELELEMENT, SimpleAASSubmodel.INTPROPIDSHORT);
+		provider.deleteValue(path);
+		assertFalse(getRemoteSubmodel().getProperties().containsKey(SimpleAASSubmodel.INTPROPIDSHORT));
+	}
+
+	/**
+	 * Checks if INVOKE is correctly forwarded by checking if an operation can be
+	 * called in the remote submodel
+	 * 
+	 * @throws Exception
+	 */
+	@Test
+	public void testInvoke() throws Exception {
+		String path = VABPathTools.concatenatePaths(REMOTEPATH, Submodel.SUBMODELELEMENT, SimpleAASSubmodel.OPERATIONSIMPLEIDSHORT, Operation.INVOKE);
+		assertTrue((Boolean) provider.invokeOperation(path));
+	}
+
+	@SuppressWarnings("unchecked")
+	private Submodel getRemoteSubmodel() {
+		return Submodel.createAsFacade((Map<String, Object>) provider.getValue(REMOTEPATH));
+	}
+
+	@After
+	public void tearDown() {
+		services.forEach(b -> b.stop());
+	}
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/restapi/MultiSubmodelProviderTest.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/restapi/MultiSubmodelProviderTest.java
index 9c59cfc..87c1b84 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/restapi/MultiSubmodelProviderTest.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/restapi/MultiSubmodelProviderTest.java
@@ -10,17 +10,20 @@
 import java.util.Collection;
 import java.util.Map;
 
+import org.eclipse.basyx.aas.metamodel.api.parts.asset.AssetKind;
 import org.eclipse.basyx.aas.metamodel.connected.ConnectedAssetAdministrationShell;
 import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
 import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
+import org.eclipse.basyx.aas.metamodel.map.parts.Asset;
 import org.eclipse.basyx.aas.restapi.AASModelProvider;
-import org.eclipse.basyx.aas.restapi.VABMultiSubmodelProvider;
+import org.eclipse.basyx.aas.restapi.MultiSubmodelProvider;
 import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
 import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.submodel.restapi.SubModelProvider;
-import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation;
+import org.eclipse.basyx.submodel.restapi.MultiSubmodelElementProvider;
+import org.eclipse.basyx.submodel.restapi.SubmodelProvider;
 import org.eclipse.basyx.testsuite.regression.submodel.restapi.SimpleAASSubmodel;
 import org.eclipse.basyx.testsuite.regression.vab.manager.VABConnectionManagerStub;
 import org.eclipse.basyx.vab.exception.provider.ProviderException;
@@ -47,13 +50,12 @@
 	public void build() {
 		VABConnectionManagerStub stub = new VABConnectionManagerStub();
 		String urn = "urn:fhg:es.iese:aas:1:1:submodel";
-		VABMultiSubmodelProvider provider = new VABMultiSubmodelProvider();
+		MultiSubmodelProvider provider = new MultiSubmodelProvider();
+
 		// set dummy aas
-		AssetAdministrationShell aas = new AssetAdministrationShell();
-		aas.setIdShort(AASIDSHORT);
-		aas.setIdentification(AASURN);
+		AssetAdministrationShell aas = new AssetAdministrationShell(AASIDSHORT, AASURN, new Asset("assetIdShort", new Identifier(IdentifierType.CUSTOM, "assetId"), AssetKind.INSTANCE));
 		provider.setAssetAdministrationShell(new AASModelProvider(aas));
-		provider.addSubmodel("SimpleAASSubmodel", new SubModelProvider(new SimpleAASSubmodel()));
+		provider.addSubmodel(new SubmodelProvider(new SimpleAASSubmodel()));
 		stub.addProvider(urn, "", provider);
 		proxy = stub.connectToVABElement(urn);
 	}
@@ -65,13 +67,13 @@
 	public void invokeExceptionTest() {
 		// Invoke operationEx1
 		try {
-			proxy.invokeOperation("/aas/submodels/SimpleAASSubmodel/operations/exception1/invokable");
+			proxy.invokeOperation("/aas/submodels/SimpleAASSubmodel/submodel/submodelElements/exception1/invokable/invoke");
 			fail();
 		} catch (ProviderException e) {}
 
 		// Invoke operationEx2
 		try {
-			proxy.invokeOperation("/aas/submodels/SimpleAASSubmodel/operations/exception2/invokable", "prop1");
+			proxy.invokeOperation("/aas/submodels/SimpleAASSubmodel/submodel/submodelElements/exception2/invokable/invoke", "prop1");
 			fail();
 		} catch (ProviderException e) {}
 	}
@@ -79,29 +81,44 @@
 	@Test
 	public void invokeTest() {
 		// Invoke operation
-		assertEquals(7, proxy.invokeOperation("/aas/submodels/SimpleAASSubmodel/operations/complex", 10, 3));
-		assertEquals(true, proxy.invokeOperation("/aas/submodels/SimpleAASSubmodel/operations/simple"));
+		assertEquals(7, proxy.invokeOperation("/aas/submodels/SimpleAASSubmodel/submodel/submodelElements/complex/" + Operation.INVOKE, 10, 3));
+		assertEquals(true, proxy.invokeOperation("/aas/submodels/SimpleAASSubmodel/submodel/submodelElements/simple/" + Operation.INVOKE));
 	}
 
 	@SuppressWarnings("unchecked")
 	@Test
 	public void getTest() {
-		AssetAdministrationShell aas = AssetAdministrationShell.createAsFacade((Map<String, Object>) proxy.getModelPropertyValue("/aas"));
+		AssetAdministrationShell aas = AssetAdministrationShell.createAsFacade((Map<String, Object>) proxy.getValue("/aas"));
 		assertEquals(AASIDSHORT, aas.getIdShort());
 
 		getTestRunner("SimpleAASSubmodel");
 	}
 
 	@Test
-	public void createDeleteSubmodelTest() {
-		SubModel sm = new SimpleAASSubmodel("TestSM");
+	public void updateSubmodelTest() {
+		Submodel sm = new SimpleAASSubmodel("TestSM");
 		sm.setIdentification(IdentifierType.CUSTOM, "TestId");
-		proxy.createValue("/aas/submodels", sm);
+		proxy.setValue("/aas/submodels/" + sm.getIdShort(), sm);
+
+		Submodel sm2 = new SimpleAASSubmodel("TestSM");
+		sm2.setIdentification(IdentifierType.CUSTOM, "TestId2");
+		proxy.setValue("/aas/submodels/" + sm.getIdShort(), sm2);
+
+		ConnectedAssetAdministrationShell shell = new ConnectedAssetAdministrationShell(proxy.getDeepProxy("/aas"));
+		String newId = shell.getSubmodels().get("TestSM").getIdentification().getId();
+		assertEquals("TestId2", newId);
+	}
+
+	@Test
+	public void createDeleteSubmodelTest() {
+		Submodel sm = new SimpleAASSubmodel("TestSM");
+		sm.setIdentification(IdentifierType.CUSTOM, "TestId");
+		proxy.setValue("/aas/submodels/" + sm.getIdShort(), sm);
 
 		getTestRunner("TestSM");
 
-		// Ensure that the Submodel References where updated
-		ConnectedAssetAdministrationShell shell = new ConnectedAssetAdministrationShell(proxy.getDeepProxy("/aas"), null);
+		// Ensure that the Submodel References were updated
+		ConnectedAssetAdministrationShell shell = new ConnectedAssetAdministrationShell(proxy.getDeepProxy("/aas"));
 		Collection<IReference> refs = shell.getSubmodelReferences();
 		assertEquals(2, refs.size());
 		assertEquals(sm.getReference(), refs.iterator().next());
@@ -113,22 +130,21 @@
 		assertFalse(shell.getSubmodelReferences().contains(sm.getReference()));
 
 		try {
-			proxy.getModelPropertyValue("/aas/submodels/TestSM");
+			proxy.getValue("/aas/submodels/TestSM");
 			fail();
 		} catch (ProviderException e) {
 			// Expected
 		}
 	}
 
-	@SuppressWarnings("unchecked")
-	void getTestRunner(String smId) {
+	private void getTestRunner(String smId) {
 		// Get property value
-		Map<String, Object> value = (Map<String, Object>) proxy
-				.getModelPropertyValue("/aas/submodels/" + smId + "/" + SubmodelElementProvider.PROPERTIES + "/integerProperty/value");
-		assertEquals(123, value.get(Property.VALUE));
+		Integer value = (Integer) proxy
+				.getValue("/aas/submodels/" + smId + "/" + SubmodelProvider.SUBMODEL + "/" + MultiSubmodelElementProvider.ELEMENTS + "/integerProperty/value");
+		assertEquals(123, value.intValue());
 
 		// Get property value with /submodel suffix
-		value = (Map<String, Object>) proxy.getModelPropertyValue("/aas/submodels/" + smId + "/submodel/" + SubmodelElementProvider.PROPERTIES + "/integerProperty/value");
-		assertEquals(123, value.get(Property.VALUE));
+		value = (Integer) proxy.getValue("/aas/submodels/" + smId + "/" + SubmodelProvider.SUBMODEL + "/" + MultiSubmodelElementProvider.ELEMENTS + "/integerProperty/value");
+		assertEquals(123, value.intValue());
 	}
 }
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/restapi/StubAASServlet.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/restapi/StubAASServlet.java
index 62d0640..178f6d4 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/restapi/StubAASServlet.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/restapi/StubAASServlet.java
@@ -1,15 +1,24 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.aas.restapi;
 
 import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
 import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
 import org.eclipse.basyx.aas.restapi.AASModelProvider;
-import org.eclipse.basyx.aas.restapi.VABMultiSubmodelProvider;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
-import org.eclipse.basyx.submodel.restapi.SubModelProvider;
+import org.eclipse.basyx.aas.restapi.MultiSubmodelProvider;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.restapi.SubmodelProvider;
 import org.eclipse.basyx.testsuite.regression.submodel.restapi.SimpleAASSubmodel;
 import org.eclipse.basyx.vab.protocol.http.server.VABHTTPInterface;
 
-public class StubAASServlet extends VABHTTPInterface<VABMultiSubmodelProvider> {
+public class StubAASServlet extends VABHTTPInterface<MultiSubmodelProvider> {
 	private static final long serialVersionUID = 8859337501045845823L;
 
 	// Used short ids
@@ -21,18 +30,18 @@
 	public static final ModelUrn SMURN = new ModelUrn("urn:fhg:es.iese:aas:1:1:mySM#001");
 
 	public StubAASServlet() {
-		super(new VABMultiSubmodelProvider());
+		super(new MultiSubmodelProvider());
 
-		SubModel sm = new SubModel();
+		Submodel sm = new Submodel();
 		sm.setIdentification(SMURN.getIdType(), SMURN.getId());
 		sm.setIdShort(SMIDSHORT);
 		AssetAdministrationShell aas = new AssetAdministrationShell();
-		aas.addSubModel(sm);
+		aas.addSubmodel(sm);
 		aas.setIdShort(AASIDSHORT);
 		aas.setIdentification(AASURN);
 
 		getModelProvider().setAssetAdministrationShell(new AASModelProvider(aas));
-		getModelProvider().addSubmodel(SMIDSHORT, new SubModelProvider(new SimpleAASSubmodel(SMIDSHORT)));
+		getModelProvider().addSubmodel(new SubmodelProvider(new SimpleAASSubmodel(SMIDSHORT)));
 	}
 
 }
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/enumhelper/StandardizedLiteralEnumHelperTests.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/enumhelper/StandardizedLiteralEnumHelperTests.java
index f28728f..0917f4c 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/enumhelper/StandardizedLiteralEnumHelperTests.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/enumhelper/StandardizedLiteralEnumHelperTests.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.enumhelper;
 
 import static org.junit.Assert.assertTrue;
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/aggregator/mqtt/TestMqttAASAggregator.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/aggregator/mqtt/TestMqttAASAggregator.java
new file mode 100644
index 0000000..9ffca3b
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/aggregator/mqtt/TestMqttAASAggregator.java
@@ -0,0 +1,117 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.extensions.aas.aggregator.mqtt;
+
+import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.IOException;
+
+import org.eclipse.basyx.aas.aggregator.AASAggregator;
+import org.eclipse.basyx.aas.aggregator.api.IAASAggregator;
+import org.eclipse.basyx.aas.metamodel.api.parts.asset.AssetKind;
+import org.eclipse.basyx.aas.metamodel.map.parts.Asset;
+import org.eclipse.basyx.extensions.aas.aggregator.mqtt.MqttAASAggregator;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.eclipse.basyx.testsuite.regression.extensions.shared.mqtt.MqttTestListener;
+import org.eclipse.paho.client.mqttv3.MqttException;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import io.moquette.broker.Server;
+import io.moquette.broker.config.ClasspathResourceLoader;
+import io.moquette.broker.config.IConfig;
+import io.moquette.broker.config.IResourceLoader;
+import io.moquette.broker.config.ResourceLoaderConfig;
+
+/**
+ * Tests events emitting with the MqttAASAggregator
+ * 
+ * @author haque
+ *
+ */
+public class TestMqttAASAggregator {
+	protected AssetAdministrationShell shell;
+	private static final String AASID = "aasid1";
+	private static final Identifier AASIDENTIFIER = new Identifier(IdentifierType.IRI, AASID);
+	
+	private static Server mqttBroker;
+	private static MqttAASAggregator eventAPI;
+	private MqttTestListener listener;
+
+	/**
+	 * Sets up the MQTT broker and AASAggregator for tests
+	 */
+	@BeforeClass
+	public static void setUpClass() throws MqttException, IOException {
+		// Start MQTT broker
+		mqttBroker = new Server();
+		IResourceLoader classpathLoader = new ClasspathResourceLoader();
+		final IConfig classPathConfig = new ResourceLoaderConfig(classpathLoader);
+		mqttBroker.startServer(classPathConfig);
+
+		// Create underlying aas aggregator
+		IAASAggregator aggregator = new AASAggregator();
+		
+		eventAPI = new MqttAASAggregator(aggregator, "tcp://localhost:1884", "testClient");
+	}
+
+	@AfterClass
+	public static void tearDownClass() {
+		mqttBroker.stopServer();
+	}
+	
+	@Before
+	public void setUp() {
+		shell = new AssetAdministrationShell(AASID, AASIDENTIFIER, new Asset("assetid1", new Identifier(IdentifierType.IRI, "assetid1"), AssetKind.INSTANCE));
+		eventAPI.createAAS(shell);
+		
+		listener = new MqttTestListener();
+		mqttBroker.addInterceptHandler(listener);
+	}
+	
+	@After
+	public void tearDown() {
+		mqttBroker.removeInterceptHandler(listener);
+	}
+	
+	@Test
+	public void testCreateAAS() {
+		String aasId2 = "aas2";
+		Identifier identifier2 = new Identifier(IdentifierType.IRDI, aasId2);
+		AssetAdministrationShell shell2 = new AssetAdministrationShell(aasId2, identifier2, new Asset("assetid2", new Identifier(IdentifierType.IRI, "assetid2"), AssetKind.INSTANCE));
+		eventAPI.createAAS(shell2);
+
+		assertEquals(aasId2, listener.lastPayload);
+		assertEquals(MqttAASAggregator.TOPIC_CREATEAAS, listener.lastTopic);
+	}
+	
+	@Test
+	public void testUpdateAAS() {
+		shell.setCategory("newCategory");
+		eventAPI.updateAAS(shell);
+		
+		assertEquals(AASID, listener.lastPayload);
+		assertEquals(MqttAASAggregator.TOPIC_UPDATEAAS, listener.lastTopic);
+	}
+	
+	@Test
+	public void testDeleteAAS() {
+		eventAPI.deleteAAS(AASIDENTIFIER);
+
+		assertEquals(AASID, listener.lastPayload);
+		assertEquals(MqttAASAggregator.TOPIC_DELETEAAS, listener.lastTopic);
+	}
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/directory/tagged/TestTaggedDirectorySuite.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/directory/tagged/TestTaggedDirectorySuite.java
index acc5e24..1d83683 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/directory/tagged/TestTaggedDirectorySuite.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/directory/tagged/TestTaggedDirectorySuite.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.extensions.aas.directory.tagged;
 
 import static org.junit.Assert.assertEquals;
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/directory/tagged/map/TestMapTaggedDirectory.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/directory/tagged/map/TestMapTaggedDirectory.java
index 51f89fb..9545598 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/directory/tagged/map/TestMapTaggedDirectory.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/directory/tagged/map/TestMapTaggedDirectory.java
@@ -1,8 +1,17 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.extensions.aas.directory.tagged.map;
 
 import java.util.HashMap;
 
-import org.eclipse.basyx.aas.registration.api.IAASRegistryService;
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
 import org.eclipse.basyx.extensions.aas.directory.tagged.api.IAASTaggedDirectory;
 import org.eclipse.basyx.extensions.aas.directory.tagged.map.MapTaggedDirectory;
 import org.eclipse.basyx.testsuite.regression.extensions.aas.directory.tagged.TestTaggedDirectorySuite;
@@ -21,7 +30,7 @@
 	}
 
 	@Override
-	protected IAASRegistryService getRegistryService() {
+	protected IAASRegistry getRegistryService() {
 		return getDirectory();
 	}
 
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/directory/tagged/proxy/TestProxyTaggedDirectory.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/directory/tagged/proxy/TestProxyTaggedDirectory.java
index 1f8edef..2e9470d 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/directory/tagged/proxy/TestProxyTaggedDirectory.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/directory/tagged/proxy/TestProxyTaggedDirectory.java
@@ -1,6 +1,15 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.extensions.aas.directory.tagged.proxy;
 
-import org.eclipse.basyx.aas.registration.api.IAASRegistryService;
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
 import org.eclipse.basyx.extensions.aas.directory.tagged.api.IAASTaggedDirectory;
 import org.eclipse.basyx.extensions.aas.directory.tagged.proxy.TaggedDirectoryProxy;
 import org.eclipse.basyx.extensions.aas.directory.tagged.restapi.TaggedDirectoryProvider;
@@ -14,7 +23,7 @@
 	}
 
 	@Override
-	protected IAASRegistryService getRegistryService() {
+	protected IAASRegistry getRegistryService() {
 		return getDirectory();
 	}
 
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/directory/tagged/servlet/TestTaggedDirectoryProviderHTTP.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/directory/tagged/servlet/TestTaggedDirectoryProviderHTTP.java
index 137c187..dd90a15 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/directory/tagged/servlet/TestTaggedDirectoryProviderHTTP.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/directory/tagged/servlet/TestTaggedDirectoryProviderHTTP.java
@@ -1,6 +1,15 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.extensions.aas.directory.tagged.servlet;
 
-import org.eclipse.basyx.aas.registration.api.IAASRegistryService;
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
 import org.eclipse.basyx.extensions.aas.directory.tagged.api.IAASTaggedDirectory;
 import org.eclipse.basyx.extensions.aas.directory.tagged.proxy.TaggedDirectoryProxy;
 import org.eclipse.basyx.extensions.aas.directory.tagged.restapi.TaggedDirectoryProvider;
@@ -32,7 +41,7 @@
 	public AASHTTPServerResource res = new AASHTTPServerResource(new BaSyxContext("/basys.sdk", System.getProperty("java.io.tmpdir")).addServletMapping("/Testsuite/directory/*", new TaggedDirectoryProviderServlet()));
 
 	@Override
-	protected IAASRegistryService getRegistryService() {
+	protected IAASRegistry getRegistryService() {
 		return getDirectory();
 	}
 
@@ -41,4 +50,4 @@
 		return new TaggedDirectoryProxy("http://localhost:8080/basys.sdk/Testsuite/directory");
 	}
 
-}
\ No newline at end of file
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/registration/mqtt/TestMqttAASRegistryService.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/registration/mqtt/TestMqttAASRegistryService.java
new file mode 100644
index 0000000..e6f3ac3
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/registration/mqtt/TestMqttAASRegistryService.java
@@ -0,0 +1,144 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.extensions.aas.registration.mqtt;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.IOException;
+
+import org.eclipse.basyx.aas.metamodel.api.parts.asset.AssetKind;
+import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
+import org.eclipse.basyx.aas.metamodel.map.parts.Asset;
+import org.eclipse.basyx.aas.registration.api.IAASRegistry;
+import org.eclipse.basyx.aas.registration.memory.InMemoryRegistry;
+import org.eclipse.basyx.extensions.aas.registration.mqtt.MqttAASRegistryService;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.eclipse.basyx.testsuite.regression.extensions.shared.mqtt.MqttTestListener;
+import org.eclipse.paho.client.mqttv3.MqttException;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import io.moquette.broker.Server;
+import io.moquette.broker.config.ClasspathResourceLoader;
+import io.moquette.broker.config.IConfig;
+import io.moquette.broker.config.IResourceLoader;
+import io.moquette.broker.config.ResourceLoaderConfig;
+
+/**
+ * Tests events emitting with the MqttAASRegistryService
+ * 
+ * @author haque
+ *
+ */
+public class TestMqttAASRegistryService {
+	
+	private static final String AASID = "aasid1";
+	private static final String SUBMODELID = "submodelid1";
+	private static final String AASENDPOINT = "http://localhost:8080/aasList/" + AASID + "/aas";
+	private static final Identifier AASIDENTIFIER = new Identifier(IdentifierType.IRI, AASID);
+	private static final Identifier SUBMODELIDENTIFIER = new Identifier(IdentifierType.IRI, SUBMODELID);
+	
+	private static Server mqttBroker;
+	private static MqttAASRegistryService eventAPI;
+	private MqttTestListener listener;
+
+	/**
+	 * Sets up the MQTT broker and AASRegistryService for tests
+	 */
+	@BeforeClass
+	public static void setUpClass() throws MqttException, IOException {
+		// Start MQTT broker
+		mqttBroker = new Server();
+		IResourceLoader classpathLoader = new ClasspathResourceLoader();
+		final IConfig classPathConfig = new ResourceLoaderConfig(classpathLoader);
+		mqttBroker.startServer(classPathConfig);
+
+		// Create underlying registry service
+		IAASRegistry registryService = new InMemoryRegistry();
+		
+		eventAPI = new MqttAASRegistryService(registryService, "tcp://localhost:1884", "testClient");
+	}
+
+	@AfterClass
+	public static void tearDownClass() {
+		mqttBroker.stopServer();
+	}
+	
+	@Before
+	public void setUp() {
+		AssetAdministrationShell shell = new AssetAdministrationShell(AASID, AASIDENTIFIER, new Asset("assetid1", new Identifier(IdentifierType.IRI, "assetid1"), AssetKind.INSTANCE));
+		AASDescriptor aasDescriptor = new AASDescriptor(shell, AASENDPOINT);
+		eventAPI.register(aasDescriptor);
+		
+		Submodel submodel = new Submodel(SUBMODELID, SUBMODELIDENTIFIER);
+		String submodelEndpoint = AASENDPOINT + "/submodels/" + SUBMODELID + "/submodel";
+		SubmodelDescriptor submodelDescriptor = new SubmodelDescriptor(submodel, submodelEndpoint);
+		eventAPI.register(AASIDENTIFIER, submodelDescriptor);
+		
+		listener = new MqttTestListener();
+		mqttBroker.addInterceptHandler(listener);
+	}
+	
+	@After
+	public void tearDown() {
+		mqttBroker.removeInterceptHandler(listener);
+	}
+	
+	@Test
+	public void testRegisterAAS() {
+		String newAASId = "aasid2";
+		Identifier newIdentifier = new Identifier(IdentifierType.IRI, newAASId);
+		AssetAdministrationShell shell = new AssetAdministrationShell(newAASId, newIdentifier, new Asset("assetid1", new Identifier(IdentifierType.IRI, "assetid2"), AssetKind.INSTANCE));
+		String aasEndpoint = "http://localhost:8080/aasList/" + newAASId + "/aas";
+		
+		AASDescriptor aasDescriptor = new AASDescriptor(shell, aasEndpoint);
+		eventAPI.register(aasDescriptor);
+		
+		assertEquals(newAASId, listener.lastPayload);
+		assertEquals(MqttAASRegistryService.TOPIC_REGISTERAAS, listener.lastTopic);
+	}
+	
+	@Test
+	public void testRegisterSubmodel() {
+		String submodelid = "submodelid2";
+		Identifier newSubmodelIdentifier = new Identifier(IdentifierType.IRI, submodelid);
+		Submodel submodel = new Submodel(submodelid, newSubmodelIdentifier);
+		String submodelEndpoint = AASENDPOINT + "/submodels/" + submodelid + "/submodel";
+		SubmodelDescriptor submodelDescriptor = new SubmodelDescriptor(submodel, submodelEndpoint);
+		
+		eventAPI.register(AASIDENTIFIER, submodelDescriptor);
+		
+		assertEquals(MqttAASRegistryService.concatAasSmId(AASIDENTIFIER, newSubmodelIdentifier), listener.lastPayload);
+		assertEquals(MqttAASRegistryService.TOPIC_REGISTERSUBMODEL, listener.lastTopic);
+	}
+	
+	@Test
+	public void testDeleteAAS() {
+		eventAPI.delete(AASIDENTIFIER);
+		
+		assertEquals(AASID, listener.lastPayload);
+		assertEquals(MqttAASRegistryService.TOPIC_DELETEAAS, listener.lastTopic);
+	}
+	
+	@Test
+	public void testDeleteSubmodel() {
+		eventAPI.delete(AASIDENTIFIER, SUBMODELIDENTIFIER);
+
+		assertEquals(MqttAASRegistryService.concatAasSmId(AASIDENTIFIER, SUBMODELIDENTIFIER), listener.lastPayload);
+		assertEquals(MqttAASRegistryService.TOPIC_DELETESUBMODEL, listener.lastTopic);
+	}
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/shared/mqtt/MqttTestListener.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/shared/mqtt/MqttTestListener.java
new file mode 100644
index 0000000..ab2d192
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/shared/mqtt/MqttTestListener.java
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.extensions.shared.mqtt;
+
+import java.nio.charset.StandardCharsets;
+
+import io.moquette.interception.InterceptHandler;
+import io.moquette.interception.messages.InterceptAcknowledgedMessage;
+import io.moquette.interception.messages.InterceptConnectMessage;
+import io.moquette.interception.messages.InterceptConnectionLostMessage;
+import io.moquette.interception.messages.InterceptDisconnectMessage;
+import io.moquette.interception.messages.InterceptPublishMessage;
+import io.moquette.interception.messages.InterceptSubscribeMessage;
+import io.moquette.interception.messages.InterceptUnsubscribeMessage;
+
+/**
+ * Very simple MQTT broker listener for testing Submodel API events.
+ * Stores the last received event and makes its topic and payload available for reading.
+ * 
+ * @author espen
+ *
+ */
+public class MqttTestListener implements InterceptHandler {
+	// Topic and payload of the most recent event
+	public String lastTopic;
+	public String lastPayload;
+
+	@Override
+	public String getID() {
+		return null;
+	}
+
+	@Override
+	public Class<?>[] getInterceptedMessageTypes() {
+		return null;
+	}
+
+	@Override
+	public void onConnect(InterceptConnectMessage arg0) {
+	}
+
+	@Override
+	public void onConnectionLost(InterceptConnectionLostMessage arg0) {
+	}
+
+	@Override
+	public void onDisconnect(InterceptDisconnectMessage arg0) {
+	}
+
+	@Override
+	public void onMessageAcknowledged(InterceptAcknowledgedMessage arg0) {
+	}
+
+	@Override
+	public void onPublish(InterceptPublishMessage msg) {
+		lastTopic = msg.getTopicName();
+		lastPayload = msg.getPayload().toString(StandardCharsets.UTF_8);
+	}
+
+	@Override
+	public void onSubscribe(InterceptSubscribeMessage arg0) {
+	}
+
+	@Override
+	public void onUnsubscribe(InterceptUnsubscribeMessage arg0) {
+	}
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/submodel/mqtt/TestMqttSubmodelAPIEvents.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/submodel/mqtt/TestMqttSubmodelAPIEvents.java
new file mode 100644
index 0000000..87bbad5
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/submodel/mqtt/TestMqttSubmodelAPIEvents.java
@@ -0,0 +1,142 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.extensions.submodel.mqtt;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+
+import java.io.IOException;
+
+import org.eclipse.basyx.extensions.submodel.mqtt.MqttSubmodelAPI;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.restapi.vab.VABSubmodelAPI;
+import org.eclipse.basyx.testsuite.regression.extensions.shared.mqtt.MqttTestListener;
+import org.eclipse.basyx.vab.modelprovider.map.VABMapProvider;
+import org.eclipse.paho.client.mqttv3.MqttException;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import io.moquette.broker.Server;
+import io.moquette.broker.config.ClasspathResourceLoader;
+import io.moquette.broker.config.IConfig;
+import io.moquette.broker.config.IResourceLoader;
+import io.moquette.broker.config.ResourceLoaderConfig;
+
+/**
+ * Tests events emitting with the MqttSubmodelAPI
+ * 
+ * @author espen
+ *
+ */
+public class TestMqttSubmodelAPIEvents {
+	private static final String AASID = "testaasid";
+	private static final String SUBMODELID = "testsubmodelid";
+	
+	private static Server mqttBroker;
+	private static MqttSubmodelAPI eventAPI;
+	private MqttTestListener listener;
+
+	/**
+	 * Sets up the MQTT broker and submodelAPI for tests
+	 */
+	@BeforeClass
+	public static void setUpClass() throws MqttException, IOException {
+		// Start MQTT broker
+		mqttBroker = new Server();
+		IResourceLoader classpathLoader = new ClasspathResourceLoader();
+		final IConfig classPathConfig = new ResourceLoaderConfig(classpathLoader);
+		mqttBroker.startServer(classPathConfig);
+
+		// Create submodel
+		Submodel sm = new Submodel(SUBMODELID, new Identifier(IdentifierType.CUSTOM, SUBMODELID));
+		Reference parentRef = new Reference(new Key(KeyElements.ASSETADMINISTRATIONSHELL, true, AASID, IdentifierType.IRDI));
+		sm.setParent(parentRef);
+		
+		VABSubmodelAPI vabAPI = new VABSubmodelAPI(new VABMapProvider(sm));
+		eventAPI = new MqttSubmodelAPI(vabAPI, "tcp://localhost:1884", "testClient");
+	}
+
+	@AfterClass
+	public static void tearDownClass() {
+		mqttBroker.stopServer();
+	}
+	
+	@Before
+	public void setUp() {
+		listener = new MqttTestListener();
+		mqttBroker.addInterceptHandler(listener);
+	}
+	
+	@After
+	public void tearDown() {
+		mqttBroker.removeInterceptHandler(listener);
+	}
+
+	@Test
+	public void testAddSubmodelElement() throws InterruptedException {
+		String elemIdShort = "testAddProp"; 
+		Property prop = new Property(true);
+		prop.setIdShort(elemIdShort);
+		eventAPI.addSubmodelElement(prop);
+
+		assertEquals(MqttSubmodelAPI.getCombinedMessage(AASID, SUBMODELID, elemIdShort), listener.lastPayload);
+		assertEquals(MqttSubmodelAPI.TOPIC_ADDELEMENT, listener.lastTopic);
+	}
+
+	@Test
+	public void testAddNestedSubmodelElement() {
+		String idShortPath = "/testColl/testAddProp/";
+		SubmodelElementCollection coll = new SubmodelElementCollection();
+		coll.setIdShort("testColl");
+		eventAPI.addSubmodelElement(coll);
+
+		Property prop = new Property(true);
+		prop.setIdShort("testAddProp");
+		eventAPI.addSubmodelElement(idShortPath, prop);
+
+		assertEquals(MqttSubmodelAPI.getCombinedMessage(AASID, SUBMODELID, idShortPath), listener.lastPayload);
+		assertEquals(MqttSubmodelAPI.TOPIC_ADDELEMENT, listener.lastTopic);
+	}
+
+	@Test
+	public void testDeleteSubmodelElement() {
+		String idShortPath = "/testDeleteProp";
+		Property prop = new Property(true);
+		prop.setIdShort("testDeleteProp");
+		eventAPI.addSubmodelElement(prop);
+		eventAPI.deleteSubmodelElement(idShortPath);
+
+		assertEquals(MqttSubmodelAPI.getCombinedMessage(AASID, SUBMODELID, idShortPath), listener.lastPayload);
+		assertEquals(MqttSubmodelAPI.TOPIC_DELETEELEMENT, listener.lastTopic);
+	}
+
+	@Test
+	public void testUpdateSubmodelElement() {
+		String idShortPath = "testUpdateProp";
+		Property prop = new Property(true);
+		prop.setIdShort(idShortPath);
+		eventAPI.addSubmodelElement(prop);
+		eventAPI.updateSubmodelElement(idShortPath, false);
+
+		assertFalse((boolean) eventAPI.getSubmodelElementValue(idShortPath));
+		assertEquals(MqttSubmodelAPI.getCombinedMessage(AASID, SUBMODELID, idShortPath), listener.lastPayload);
+		assertEquals(MqttSubmodelAPI.TOPIC_UPDATEELEMENT, listener.lastTopic);
+	}
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/TestSubmodelSuite.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/TestSubmodelSuite.java
new file mode 100644
index 0000000..63f0540
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/TestSubmodelSuite.java
@@ -0,0 +1,408 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.submodel.metamodel;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.math.BigInteger;
+import java.time.Duration;
+import java.time.LocalDate;
+import java.time.Month;
+import java.time.Period;
+import java.util.ArrayList;
+import java.util.Base64;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElementCollection;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IDataElement;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangString;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangStrings;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.Blob;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.File;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.MultiLanguageProperty;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.ReferenceElement;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.range.Range;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.range.RangeValue;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.relationship.AnnotatedRelationshipElement;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.relationship.RelationshipElement;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.junit.Test;
+
+/**
+ * Abstract Submodel Testsuite to be reused by different implementations of
+ * {@link ISubmodel}
+ * 
+ * @author schnicke
+ *
+ */
+public abstract class TestSubmodelSuite {
+	// String constants used in this test case
+	private final static String PROP = "prop1";
+	private final static String ID = "TestId";
+
+	private final String PROPERTY_ID = "property_id";
+	private final String BLOB_ID = "blob_id";
+	private final String RELATIONSHIP_ELEM_ID = "relElem_id";
+	private final String ANNOTATED_RELATIONSHIP_ELEM_ID = "annotatedRelElem_id";
+	private final String SUBMODEL_ELEM_COLLECTION_ID = "elemCollection_id";
+	private final String PROPERTY_CONTAINED_ID = "containedProp";
+	private final String RANGE_ID = "range_id";
+	private final String FILE_ID = "file_id";
+	private final String MULTI_LANG_PROP_ID = "multi_lang_prop_id";
+	private final String REFERENCE_ELEMENT_ID = "reference_element_id";
+	private final String PROPERTY_ID2 = "property_id2";
+	
+
+	private final static Reference testSemanticIdRef = new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "testVal", IdentifierType.CUSTOM));
+
+	public Submodel getReferenceSubmodel() {
+
+		// Create a simple value property
+		Property propertyMeta = new Property(PROP, ValueType.Integer);
+		propertyMeta.setValue(100);
+
+		// Create the Submodel using the created property and operation
+		IIdentifier submodelId = new ModelUrn("testUrn");
+		Submodel localSubmodel = new Submodel(ID, submodelId);
+		localSubmodel.addSubmodelElement(propertyMeta);
+		localSubmodel.setSemanticId(testSemanticIdRef);
+
+		return localSubmodel;
+	}
+
+	protected abstract ISubmodel getSubmodel();
+
+	/**
+	 * Tests if a Submodel's id can be retrieved correctly
+	 */
+	@Test
+	public void getIdTest() {
+		ISubmodel submodel = getSubmodel();
+		assertEquals(ID, submodel.getIdShort());
+	}
+
+	/**
+	 * Tests if a Submodel's properties can be used correctly
+	 */
+	@Test
+	public void propertiesTest() throws Exception {
+		ISubmodel submodel = getSubmodel();
+		// Retrieve all properties
+		Map<String, IProperty> props = submodel.getProperties();
+
+		// Check if number of properties is as expected
+		assertEquals(1, props.size());
+
+		// Check the value of the property
+		IProperty prop = props.get(PROP);
+		assertEquals(100, prop.getValue());
+	}
+
+
+	@Test
+	public void saveAndLoadPropertyTest() throws Exception {
+		ISubmodel submodel = getSubmodel();
+
+		// Get sample DataElements and save them into Submodel
+		Map<String, IProperty> testData = getTestDataProperty();
+		for (ISubmodelElement element : testData.values()) {
+			submodel.addSubmodelElement(element);
+		}
+
+		// Load it
+		Map<String, IProperty> map = submodel.getProperties();
+
+		// Check if it loaded correctly
+		checkProperties(map);
+	}
+
+	@Test
+	public void saveAndLoadSubmodelElementTest() throws Exception {
+		ISubmodel submodel = getSubmodel();
+
+		// Get sample DataElements and save them into Submodel
+		Map<String, IProperty> testDataElements = getTestDataProperty();
+		for (ISubmodelElement element : testDataElements.values()) {
+			submodel.addSubmodelElement(element);
+		}
+
+
+		// Get sample SubmodelElements and save them into Submodel
+		Map<String, ISubmodelElement> testSMElements = getTestSubmodelElements();
+		for (ISubmodelElement element : testSMElements.values()) {
+			submodel.addSubmodelElement(element);
+		}
+
+		// Load it
+		Map<String, ISubmodelElement> map = submodel.getSubmodelElements();
+
+		// Check if it loaded correctly
+		// Including DataElements and Operations as they are also SubmodelElements
+		checkProperties(map);
+		checkSubmodelElements(map);
+	}
+
+	/**
+	 * Tests if the semantic Id can be retrieved correctly
+	 */
+	@Test
+	public void semanticIdRetrievalTest() {
+		ISubmodel submodel = getSubmodel();
+		IReference ref = submodel.getSemanticId();
+		assertEquals(testSemanticIdRef, ref);
+	}
+
+	/**
+	 * Tests if the adding a submodel element is correctly done Also checks the
+	 * addition of parent reference to the submodel
+	 */
+	@Test
+	public void addSubmodelElementTest() throws Exception {
+		ISubmodel submodel = getSubmodel();
+		Property property = new Property("testProperty");
+		property.setIdShort("testIdShort");
+		submodel.addSubmodelElement(property);
+
+		IProperty connectedProperty = (IProperty) submodel.getSubmodelElements().get("testIdShort");
+		assertEquals(property.getIdShort(), connectedProperty.getIdShort());
+		assertEquals(property.getValue(), connectedProperty.getValue());
+
+		// creates an expected reference for assertion
+		IReference expected = submodel.getReference();
+		assertEquals(expected, property.getParent());
+	}
+
+	@Test
+	public void testGetSubmodelElement() {
+		ISubmodel submodel = getSubmodel();
+		ISubmodelElement element = submodel.getSubmodelElement(PROP);
+		assertEquals(PROP, element.getIdShort());
+	}
+
+	@Test(expected = ResourceNotFoundException.class)
+	public void testDeleteSubmodelElement() {
+
+		ISubmodel submodel = getSubmodel();
+		submodel.deleteSubmodelElement(PROP);
+		submodel.getSubmodelElement(PROP);
+	}
+
+	/**
+	 * Tests getValues function
+	 */
+	@SuppressWarnings("unchecked")
+	@Test
+	public void testGetValues() {
+		ISubmodel submodel = getSubmodel();
+
+		// Add elements to the Submodel
+		Map<String, ISubmodelElement> testSMElements = getTestSubmodelElements();
+		for (ISubmodelElement element : testSMElements.values()) {
+			submodel.addSubmodelElement(element);
+		}
+
+		Map<String, Object> values = submodel.getValues();
+
+		assertEquals(10, values.size());
+
+		// Check if all expected Values are present
+		assertEquals(100, values.get(PROP));
+		assertEquals(Base64.getEncoder().encodeToString(new byte[] { 1, 2, 3 }), values.get(BLOB_ID));
+
+		assertTrue(values.containsKey(RELATIONSHIP_ELEM_ID));
+		assertTrue(values.containsKey(SUBMODEL_ELEM_COLLECTION_ID));
+		Map<String, Object> collection = (Map<String, Object>) values.get(SUBMODEL_ELEM_COLLECTION_ID);
+		assertTrue(collection.containsKey(PROPERTY_CONTAINED_ID));
+		assertTrue(values.containsKey(PROPERTY_ID2));
+		assertTrue(values.containsKey(BLOB_ID));
+		assertTrue(values.containsKey(RANGE_ID));
+		assertTrue(values.containsKey(MULTI_LANG_PROP_ID));
+		assertTrue(values.containsKey(FILE_ID));
+		assertTrue(values.containsKey(REFERENCE_ELEMENT_ID));
+	}
+
+	/**
+	 * Generates test IDataElements
+	 */
+	private Map<String, IProperty> getTestDataProperty() {
+		Map<String, IProperty> ret = new HashMap<>();
+
+		Property property = new Property();
+		property.setIdShort(PROPERTY_ID);
+		property.setValue("test2");
+		ret.put(property.getIdShort(), property);
+
+		Property byteProp = new Property();
+		byteProp.setIdShort("byte_prop01");
+		Byte byteNumber = Byte.parseByte("2");
+		byteProp.setValue(byteNumber);
+		ret.put(byteProp.getIdShort(), byteProp);
+
+		Property durationProp = new Property();
+		durationProp.setIdShort("duration_prop01");
+		Duration duration = Duration.ofSeconds(10);
+		durationProp.setValue(duration);
+		ret.put(durationProp.getIdShort(), durationProp);
+
+		Property periodProp = new Property();
+		periodProp.setIdShort("period_prop01");
+		LocalDate today = LocalDate.now();
+		LocalDate birthday = LocalDate.of(1960, Month.JANUARY, 1);
+		Period p = Period.between(birthday, today);
+		periodProp.setValue(p);
+		ret.put(periodProp.getIdShort(), periodProp);
+
+		Property bigNumberProp = new Property();
+		bigNumberProp.setIdShort("bignumber_prop01");
+		BigInteger bignumber = new BigInteger("9223372036854775817");
+		property.setValue(bignumber);
+		ret.put(bigNumberProp.getIdShort(), bigNumberProp);
+
+		return ret;
+	}
+	/**
+	 * Generates test ISubmodelElements
+	 */
+	private Map<String, ISubmodelElement> getTestSubmodelElements() {
+		Map<String, ISubmodelElement> ret = new HashMap<>();
+
+		SubmodelElementCollection smECollection = new SubmodelElementCollection();
+		smECollection.setIdShort(SUBMODEL_ELEM_COLLECTION_ID);
+
+		// Create a Property to use as Value for smECollection
+		List<ISubmodelElement> values = new ArrayList<>();
+		Property contained = new Property(PROPERTY_CONTAINED_ID, true);
+		values.add(contained);
+
+
+		smECollection.setValue(values);
+		ret.put(smECollection.getIdShort(), smECollection);
+
+		Blob blob = new Blob(BLOB_ID, "text/json");
+		blob.setByteArrayValue(new byte[] { 1, 2, 3 });
+		ret.put(blob.getIdShort(), blob);
+
+		Reference first = new Reference(new Key(KeyElements.BASICEVENT, true, "testFirst", IdentifierType.CUSTOM));
+		Reference second = new Reference(new Key(KeyElements.BASICEVENT, true, "testSecond", IdentifierType.CUSTOM));
+		
+		RelationshipElement relElement = new RelationshipElement(RELATIONSHIP_ELEM_ID, first, second);
+		ret.put(relElement.getIdShort(), relElement);
+
+		AnnotatedRelationshipElement annotatedRelElement = new AnnotatedRelationshipElement(ANNOTATED_RELATIONSHIP_ELEM_ID, first, second);
+		List<IDataElement> annotations = new ArrayList<>();
+		Property annotationProperty = new Property("id", 10);
+		annotations.add(annotationProperty);
+		annotatedRelElement.setAnnotation(annotations);
+		ret.put(annotatedRelElement.getIdShort(), annotatedRelElement);
+		
+		Property property = new Property(PROPERTY_ID2, ValueType.AnySimpleType);
+		ret.put(property.getIdShort(), property);
+		
+		Range range = new Range(RANGE_ID, ValueType.Integer);
+		range.setValue(new RangeValue(-100, +100));
+		ret.put(range.getIdShort(), range);
+		
+		File file = new File("text/plain");
+		file.setIdShort(FILE_ID);
+		file.setValue("fileUrl");
+		ret.put(file.getIdShort(), file);
+		
+		MultiLanguageProperty languageProperty = new MultiLanguageProperty(MULTI_LANG_PROP_ID);
+		languageProperty.setValue(new LangStrings(new LangString("en-en", "TestDescription")));
+		ret.put(languageProperty.getIdShort(), languageProperty);
+		
+		ReferenceElement referenceElement = new ReferenceElement(REFERENCE_ELEMENT_ID, first);
+		ret.put(referenceElement.getIdShort(), referenceElement);
+
+		return ret;
+	}
+
+	/**
+	 * Checks if the given Map contains all expected IDataElements
+	 */
+	private void checkProperties(Map<String, ? extends ISubmodelElement> actual) throws Exception {
+		assertNotNull(actual);
+
+		Map<String, IProperty> expected = getTestDataProperty();
+
+		// Check value and type of each property in the submodel
+		expected.forEach((id, prop) -> {
+			IProperty expectedProperty = expected.get(PROPERTY_ID);
+			IProperty actualProperty = (IProperty) actual.get(PROPERTY_ID);
+			assertNotNull(actualProperty);
+			try {
+				assertEquals(expectedProperty.getValue(), actualProperty.getValue());
+				assertEquals(expectedProperty.getValueType(), actualProperty.getValueType());
+			} catch (Exception e) {
+				e.printStackTrace();
+			}
+		});
+	}
+
+	/**
+	 * Checks if the given Map contains all expected ISubmodelElements
+	 */
+	private void checkSubmodelElements(Map<String, ISubmodelElement> actual) throws Exception {
+		assertNotNull(actual);
+
+		Map<String, ISubmodelElement> expected = getTestSubmodelElements();
+
+		ISubmodelElementCollection expectedCollection = (ISubmodelElementCollection) expected.get(SUBMODEL_ELEM_COLLECTION_ID);
+		ISubmodelElementCollection actualCollection = (ISubmodelElementCollection) actual.get(SUBMODEL_ELEM_COLLECTION_ID);
+
+		assertNotNull(actualCollection);
+
+		Collection<ISubmodelElement> elements = actualCollection.getSubmodelElements().values();
+
+
+		// Check for correct Type
+		assertEquals(1, elements.size());
+		assertTrue(elements.iterator().next() instanceof IProperty);
+
+		assertEquals(expectedCollection.getSubmodelElements().size(), elements.size());
+
+		// Check value of all submodel elements
+		for (ISubmodelElement elem : expected.values()) {
+			// Equality of Ids is implicitly checked by this retrieval
+			ISubmodelElement actualElem = actual.get(elem.getIdShort());
+			assertNotNull(actualElem);
+
+			assertEquals(elem.getValue(), actualElem.getValue());
+		}
+	}
+
+	/**
+	 * This method tests deleteSubmodelElement method of Submodel class with non
+	 * existing element id
+	 */
+	@Test(expected = ResourceNotFoundException.class)
+	public void testDeleteSubmodelElementNotExist() {
+		getSubmodel().deleteSubmodelElement("Id_Which_Does_Not_Exist");
+	}
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/api/qualifier/TestIdShortValidator.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/api/qualifier/TestIdShortValidator.java
new file mode 100644
index 0000000..0ef7980
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/api/qualifier/TestIdShortValidator.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.submodel.metamodel.api.qualifier;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.eclipse.basyx.submodel.metamodel.api.qualifier.IdShortValidator;
+import org.junit.Test;
+
+/**
+ * Tests the IdShortValidator's capability to validate IdShorts
+ * 
+ * @author schnicke
+ *
+ */
+public class TestIdShortValidator {
+
+	@Test
+	public void testValidator() {
+		String[] accepted = {"abc", "AbC"};
+		String[] notAccepted = { ":", " test", "1Test", "äTest", null, "" };
+
+		for (String s : accepted) {
+			assertTrue(s + " was not tested valid", IdShortValidator.isValid(s));
+		}
+
+		for (String s : notAccepted) {
+			assertFalse(s + " was not tested invalid", IdShortValidator.isValid(s));
+		}
+	}
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/api/submodelelement/TestSubmodelElementIdShortBlacklist.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/api/submodelelement/TestSubmodelElementIdShortBlacklist.java
new file mode 100644
index 0000000..95602e2
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/api/submodelelement/TestSubmodelElementIdShortBlacklist.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.submodel.metamodel.api.submodelelement;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.SubmodelElementIdShortBlacklist;
+import org.junit.Test;
+
+/**
+ * Tests if the SubmodelElementIdShortBlacklist works as intended
+ * 
+ * @author schnicke
+ *
+ */
+public class TestSubmodelElementIdShortBlacklist {
+
+	@Test
+	public void testIsBlacklisted() {
+		String allowed[] = { "test", "values", "invocations" };
+		
+		for (String s : SubmodelElementIdShortBlacklist.BLACKLIST) {
+			assertTrue(s + " was incorrectly allowed", SubmodelElementIdShortBlacklist.isBlacklisted(s));
+		}
+
+		for (String s : allowed) {
+			assertFalse(s + " was incorrectly blacklisted", SubmodelElementIdShortBlacklist.isBlacklisted(s));
+		}
+	}
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/TestConnectedProperty.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/TestConnectedProperty.java
index 5fceb14..8b24e4e 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/TestConnectedProperty.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/TestConnectedProperty.java
@@ -1,14 +1,27 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.submodel.metamodel.connected;
 
 import static org.junit.Assert.assertEquals;
 
 import java.util.Map;
 
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
 import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
 import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.dataelement.ConnectedProperty;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetypedef.PropertyValueTypeDef;
-import org.eclipse.basyx.submodel.restapi.PropertyProvider;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
 import org.eclipse.basyx.testsuite.regression.vab.manager.VABConnectionManagerStub;
 import org.eclipse.basyx.vab.modelprovider.map.VABMapProvider;
 import org.eclipse.basyx.vab.support.TypeDestroyer;
@@ -25,25 +38,27 @@
 
 	IProperty prop;
 	private static final int VALUE = 10;
+	private static final Reference VALUEID = new Reference(new Key(KeyElements.ACCESSPERMISSIONRULE, true, "testValue", IdentifierType.CUSTOM));
 
 	@Before
 	public void build() {
 		// Create PropertySingleValued containing the simple value
-		Property propertyMeta = new Property(VALUE);
+		Property propertyMeta = new Property("testProp", VALUE);
+		propertyMeta.setValueId(VALUEID);
 		Map<String, Object> destroyType = TypeDestroyer.destroyType(propertyMeta);
-		prop = new ConnectedProperty(new VABConnectionManagerStub(new PropertyProvider(new VABMapProvider(destroyType))).connectToVABElement(""));
+		prop = new ConnectedProperty(new VABConnectionManagerStub(new SubmodelElementProvider(new VABMapProvider(destroyType))).connectToVABElement(""));
 	}
 
 	@Test
 	public void testEmptyProperty() throws Exception {
-		Property propertyMeta = new Property();
-		propertyMeta.setValueType(PropertyValueTypeDef.String);
+		Property propertyMeta = new Property("testIdShort", ValueType.String);
+		propertyMeta.setValue(null);
 		Map<String, Object> destroyType = TypeDestroyer.destroyType(propertyMeta);
 		prop = new ConnectedProperty(
-				new VABConnectionManagerStub(new PropertyProvider(new VABMapProvider(destroyType)))
+				new VABConnectionManagerStub(new SubmodelElementProvider(new VABMapProvider(destroyType)))
 						.connectToVABElement(""));
-		prop.set("content");
-		assertEquals("content", prop.get());
+		prop.setValue("content");
+		assertEquals("content", prop.getValue());
 	}
 
 	/**
@@ -53,7 +68,7 @@
 	 */
 	@Test
 	public void testGet() throws Exception {
-		int val = (int) prop.get();
+		int val = (int) prop.getValue();
 		assertEquals(VALUE, val);
 	}
 
@@ -64,8 +79,8 @@
 	 */
 	@Test
 	public void testValueTypeRetrieval() {
-		String valueType = prop.getValueType();
-		assertEquals(PropertyValueTypeDef.Integer.toString(), valueType);
+		ValueType valueType = prop.getValueType();
+		assertEquals(ValueType.Integer, valueType);
 	}
 
 	/**
@@ -75,9 +90,14 @@
 	 */
 	@Test
 	public void testSet() throws Exception {
-		prop.set(123);
-		int val = (int) prop.get();
+		prop.setValue(123);
+		int val = (int) prop.getValue();
 		assertEquals(123, val);
 	}
 
+	@Test
+	public void testGetValueId() {
+		assertEquals(VALUEID, prop.getValueId());
+	}
+
 }
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/TestConnectedSubModel.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/TestConnectedSubModel.java
deleted file mode 100644
index 3a1580e..0000000
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/TestConnectedSubModel.java
+++ /dev/null
@@ -1,331 +0,0 @@
-package org.eclipse.basyx.testsuite.regression.submodel.metamodel.connected;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.function.Function;
-
-import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
-import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
-import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
-import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
-import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElementCollection;
-import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IBlob;
-import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
-import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperation;
-import org.eclipse.basyx.submodel.metamodel.api.submodelelement.relationship.IRelationshipElement;
-import org.eclipse.basyx.submodel.metamodel.connected.ConnectedSubModel;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
-import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
-import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.Blob;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.relationship.RelationshipElement;
-import org.eclipse.basyx.submodel.restapi.SubModelProvider;
-import org.eclipse.basyx.testsuite.regression.vab.manager.VABConnectionManagerStub;
-import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaProvider;
-import org.eclipse.basyx.vab.support.TypeDestroyingProvider;
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * Tests if a SubModel can be created and used correctly
- *
- * @author schnicke
- *
- */
-public class TestConnectedSubModel {
-
-	// String constants used in this test case
-	private final static String OP = "add";
-	private final static String PROP = "prop1";
-	private final static String ID = "TestId";
-	
-	private final String OPERATION_ID = "operation_id";
-	private final String PROPERTY_ID = "property_id";
-	private final String BLOB_ID = "blob_id";
-	private final String RELATIONSHIP_ELEM_ID = "relElem_id";
-	private final String SUBMODEL_ELEM_COLLECTION_ID = "elemCollection_id";
-
-	private final static Reference testSemanticIdRef = new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "testVal", IdentifierType.CUSTOM));
-
-	ConnectedSubModel submodel;
-
-	@Before
-	public void build() {
-		// Create a simple value property
-		Property propertyMeta = new Property(100);
-		propertyMeta.setIdShort(PROP);
-
-		// Create an operation
-		Operation op = new Operation((Function<Object[], Object> & Serializable) obj -> {
-			return (int) obj[0] + (int) obj[1];
-		});
-		op.setIdShort(OP);
-
-		// Create the SubModel using the created property and operation
-		SubModel sm = new SubModel();
-		sm.addSubModelElement(propertyMeta);
-		sm.addSubModelElement(op);
-		sm.setIdShort(ID);
-		sm.setSemanticId(testSemanticIdRef);
-
-		SubModelProvider provider = new SubModelProvider(new TypeDestroyingProvider(new VABLambdaProvider(sm)));
-
-		// Create the ConnectedSubModel based on the manager
-		submodel = new ConnectedSubModel(new VABConnectionManagerStub(provider).connectToVABElement(""));
-	}
-
-	/**
-	 * Tests if a SubModel's id can be retrieved correctly
-	 */
-	@Test
-	public void getIdTest() {
-		assertEquals(ID, submodel.getIdShort());
-	}
-
-	/**
-	 * Tests if a SubModel's properties can be used correctly
-	 */
-	@Test
-	public void propertiesTest() throws Exception {
-		// Retrieve all properties
-		Map<String, IProperty> props = submodel.getProperties();
-
-		// Check if number of properties is as expected
-		assertEquals(1, props.size());
-
-		// Check the value of the property
-		IProperty prop = props.get(PROP);
-		assertEquals(100, prop.get());
-	}
-
-	/**
-	 * Tests if a SubModel's operations can be used correctly
-	 * 
-	 * @throws Exception
-	 */
-	@Test
-	public void operationsTest() throws Exception {
-		// Retrieve all operations
-		Map<String, IOperation> ops = submodel.getOperations();
-
-		// Check if number of operations is as expected
-		assertEquals(1, ops.size());
-
-		// Check the operation itself
-		IOperation op = ops.get(OP);
-		assertEquals(5, op.invoke(2, 3));
-	}
-	
-	@Test
-	public void saveAndLoadPropertyTest() throws Exception {
-		
-		// Get sample DataElements and save them into SubModel
-		Map<String, IProperty> testData = getTestDataProperty();
-		for(ISubmodelElement element: testData.values()) {
-			submodel.addSubModelElement(element);
-		}
-		
-		// Load it
-		Map<String, IProperty> map = submodel.getProperties();
-		
-		// Check if it loaded correctly
-		checkProperties(map);
-	}
-	
-	@Test
-	public void saveAndLoadOperationTest() throws Exception {
-		// Get sample Operations and save them into SubModel
-		Map<String, IOperation> testOperations = getTestOperations();
-		for(ISubmodelElement element: testOperations.values()) {
-			submodel.addSubModelElement(element);
-		}
-		
-		// Load it
-		Map<String, IOperation> map = submodel.getOperations();
-		
-		// Check if it loaded correctly
-		checkOperations(map);
-	}
-	
-	
-	@Test
-	public void saveAndLoadSubmodelElementTest() throws Exception {
-		
-		// Get sample DataElements and save them into SubModel
-		Map<String, IProperty> testDataElements = getTestDataProperty();
-		for(ISubmodelElement element: testDataElements.values()) {
-			submodel.addSubModelElement(element);
-		}
-		
-		// Get sample Operations and save them into SubModel
-		Map<String, IOperation> testOperations = getTestOperations();
-		for(ISubmodelElement element: testOperations.values()) {
-			submodel.addSubModelElement(element);
-		}
-		
-		// Get sample SubmodelElements and save them into SubModel
-		Map<String, ISubmodelElement> testSMElements = getTestSubmodelElements();
-		for(ISubmodelElement element: testSMElements.values()) {
-			submodel.addSubModelElement(element);
-		}
-		
-		// Load it
-		Map<String, ISubmodelElement> map = submodel.getSubmodelElements();
-		
-		// Check if it loaded correctly
-		// Including DataElements and Operations as they are also SubmodelElements
-		checkProperties(map);
-		checkOperations(map);
-		checkSubmodelElements(map);
-	}
-
-	/**
-	 * Tests if the semantic Id can be retrieved correctly
-	 */
-	@Test
-	public void semanticIdRetrievalTest() {
-		IReference ref = submodel.getSemanticId();
-		assertEquals(testSemanticIdRef, ref);
-	}
-	
-	/**
-	 * Tests if the adding a submodel element is correctly done
-	 * Also checks the addition of parent reference to the submodel
-	 */
-	@Test
-	public void addSubModelElementTest() {
-		Property property = new Property("testProperty");
-		property.setIdShort("testIdShort");
-		submodel.addSubModelElement(property);
-		
-		// creates an expected reference for assertion
-		Reference expected = new Reference(new Key(KeyElements.SUBMODELELEMENT, true, "", IdentifierType.IRDI));
-		assertEquals(expected, property.getParent());
-	} 
-	
-	/**
-	 * Generates test IDataElements
-	 */
-	private Map<String, IProperty> getTestDataProperty() {
-		Map<String, IProperty> ret = new HashMap<>();
-		
-		Property property = new Property();
-		property.setIdShort(PROPERTY_ID);
-		property.set("test2");
-		
-		ret.put(property.getIdShort(), property);
-		return ret;
-	}
-	
-	/**
-	 * Generates test IOperations
-	 */
-	private Map<String, IOperation> getTestOperations() {
-		Map<String, IOperation> ret = new HashMap<>();
-		
-		Operation operation = new Operation();
-		operation.setIdShort(OPERATION_ID);
-		ret.put(operation.getIdShort(), operation);
-		
-		return ret;
-	}
-	
-	/**
-	 * Generates test ISubmodelElements
-	 */
-	private Map<String, ISubmodelElement> getTestSubmodelElements() {
-		Map<String, ISubmodelElement> ret = new HashMap<>();
-		
-		SubmodelElementCollection smECollection = new SubmodelElementCollection();
-		smECollection.setIdShort(SUBMODEL_ELEM_COLLECTION_ID);
-		
-		// Create a Blob to use as Value for smECollection
-		Blob blob = new Blob();
-		blob.setIdShort(BLOB_ID);
-		
-		List<ISubmodelElement> values = new ArrayList<>();
-		values.add(blob);
-		
-		smECollection.setValue(values);
-		ret.put(smECollection.getIdShort(), smECollection);
-		
-		RelationshipElement relElement = new RelationshipElement();
-		relElement.setIdShort(RELATIONSHIP_ELEM_ID);
-		ret.put(relElement.getIdShort(), relElement);
-		
-		return ret;
-	}
-	
-	
-	/**
-	 * Checks if the given Map contains all expected IDataElements
-	 */
-	private void checkProperties(Map<String, ? extends ISubmodelElement> actual) throws Exception {
-		assertNotNull(actual);
-		
-		Map<String, IProperty> expected = getTestDataProperty();
-		
-		IProperty expectedProperty = expected.get(PROPERTY_ID);
-		IProperty acutalProperty = (IProperty) actual.get(PROPERTY_ID);
-		assertNotNull(acutalProperty);
-		assertEquals(expectedProperty.get(), acutalProperty.get());
-	}
-	
-	/**
-	 * Checks if the given Map contains all expected IOperations
-	 */
-	private void checkOperations(Map<String, ? extends ISubmodelElement> actual) throws Exception {
-		assertNotNull(actual);
-		
-		Map<String, IOperation> expected = getTestOperations();
-		
-		IOperation expectedOperation = expected.get(OPERATION_ID);
-		IOperation actualOperation = (IOperation) actual.get(OPERATION_ID);
-		
-		assertNotNull(actualOperation);
-		assertEquals(expectedOperation.getIdShort(), actualOperation.getIdShort());
-	}
-	
-	/**
-	 * Checks if the given Map contains all expected ISubmodelElements
-	 */
-	private void checkSubmodelElements(Map<String, ISubmodelElement> actual) throws Exception {
-		assertNotNull(actual);
-		
-		Map<String, ISubmodelElement> expected = getTestSubmodelElements();
-		
-		ISubmodelElementCollection expectedCollection = 
-				(ISubmodelElementCollection) expected.get(SUBMODEL_ELEM_COLLECTION_ID);
-		ISubmodelElementCollection actualCollection =
-				(ISubmodelElementCollection) actual.get(SUBMODEL_ELEM_COLLECTION_ID);
-		
-		assertNotNull(actualCollection);
-		
-		Collection<ISubmodelElement> elements = actualCollection.getValue();
-		
-		// Check for correct Type
-		for (ISubmodelElement iSubmodelElement: elements) {
-			assertTrue(iSubmodelElement instanceof IBlob);
-		}
-		
-		assertEquals(expectedCollection.getValue().size(), elements.size());
-		
-		IRelationshipElement expectedRelElem = (IRelationshipElement) expected.get(RELATIONSHIP_ELEM_ID);
-		IRelationshipElement actualRelElem = (IRelationshipElement) actual.get(RELATIONSHIP_ELEM_ID);
-		
-		assertNotNull(actualRelElem);
-		assertEquals(expectedRelElem.getIdShort(), actualRelElem.getIdShort());
-	}
-	
-}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/TestConnectedSubmodel.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/TestConnectedSubmodel.java
new file mode 100644
index 0000000..0c56bc7
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/TestConnectedSubmodel.java
@@ -0,0 +1,161 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.submodel.metamodel.connected;
+
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.Serializable;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.function.Function;
+
+import org.eclipse.basyx.submodel.metamodel.api.qualifier.haskind.ModelingKind;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperation;
+import org.eclipse.basyx.submodel.metamodel.connected.ConnectedSubmodel;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.OperationVariable;
+import org.eclipse.basyx.submodel.restapi.SubmodelProvider;
+import org.eclipse.basyx.testsuite.regression.submodel.metamodel.TestSubmodelSuite;
+import org.eclipse.basyx.testsuite.regression.vab.manager.VABConnectionManagerStub;
+import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaProvider;
+import org.eclipse.basyx.vab.support.TypeDestroyer;
+import org.eclipse.basyx.vab.support.TypeDestroyingProvider;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests if a ConnectSubmodel can be created and used correctly
+ *
+ * @author schnicke
+ *
+ */
+public class TestConnectedSubmodel extends TestSubmodelSuite {
+
+	// String constants used in this test case
+	private final static String OP = "add";
+
+	private final String OPERATION_ID = "operation_id";
+
+	ConnectedSubmodel submodel;
+
+	@Before
+	public void build() {
+
+		Submodel reference = getReferenceSubmodel();
+		// Create an operation
+		Operation op = new Operation((Function<Object[], Object> & Serializable) obj -> {
+			return (int) obj[0] + (int) obj[1];
+		});
+		Property aProp = new Property("a", 1);
+		aProp.setModelingKind(ModelingKind.TEMPLATE);
+		Property bProp = new Property("b", 2);
+		bProp.setModelingKind(ModelingKind.TEMPLATE);
+		Property rProp = new Property("r", 3);
+		rProp.setModelingKind(ModelingKind.TEMPLATE);
+		OperationVariable a = new OperationVariable(aProp);
+		OperationVariable b = new OperationVariable(bProp);
+		OperationVariable r = new OperationVariable(rProp);
+		op.setInputVariables(Arrays.asList(a, b));
+		op.setOutputVariables(Collections.singletonList(r));
+		op.setIdShort(OP);
+		reference.addSubmodelElement(op);
+
+		SubmodelProvider provider = new SubmodelProvider(new TypeDestroyingProvider(new VABLambdaProvider(reference)));
+
+		// Create the ConnectedSubmodel based on the manager
+		submodel = new ConnectedSubmodel(new VABConnectionManagerStub(provider).connectToVABElement(""));
+	}
+
+	/**
+	 * Tests if a Submodel's operations can be used correctly
+	 *
+	 * @throws Exception
+	 */
+	@Test
+	public void operationsTest() throws Exception {
+		// Retrieve all operations
+		Map<String, IOperation> ops = submodel.getOperations();
+
+		// Check if number of operations is as expected
+		assertEquals(1, ops.size());
+
+		// Check the operation itself
+		IOperation op = ops.get(OP);
+		assertEquals(5, op.invoke(2, 3));
+	}
+
+	@Test
+	public void saveAndLoadOperationTest() throws Exception {
+		// Get sample Operations and save them into Submodel
+		Map<String, IOperation> testOperations = getTestOperations();
+		for (ISubmodelElement element : testOperations.values()) {
+			submodel.addSubmodelElement(element);
+		}
+
+		// Load it
+		Map<String, IOperation> map = submodel.getOperations();
+
+		// Check if it loaded correctly
+		checkOperations(map);
+	}
+
+	@Test
+	public void testGetLocalCopy() {
+		Submodel reference = getReferenceSubmodel();
+		SubmodelProvider provider = new SubmodelProvider(new TypeDestroyingProvider(new VABLambdaProvider(reference)));
+
+		// Create the ConnectedSubmodel based on the manager
+		ConnectedSubmodel cSM = new ConnectedSubmodel(new VABConnectionManagerStub(provider).connectToVABElement(""));
+
+		Object expected = TypeDestroyer.destroyType(reference);
+		Object actual = cSM.getLocalCopy();
+		assertEquals(expected, actual);
+	}
+
+	/**
+	 * Generates test IOperations
+	 */
+	private Map<String, IOperation> getTestOperations() {
+		Map<String, IOperation> ret = new HashMap<>();
+
+		Operation operation = new Operation();
+		operation.setIdShort(OPERATION_ID);
+		ret.put(operation.getIdShort(), operation);
+
+		return ret;
+	}
+
+	/**
+	 * Checks if the given Map contains all expected IOperations
+	 */
+	private void checkOperations(Map<String, ? extends ISubmodelElement> actual) throws Exception {
+		assertNotNull(actual);
+
+		Map<String, IOperation> expected = getTestOperations();
+
+		IOperation expectedOperation = expected.get(OPERATION_ID);
+		IOperation actualOperation = (IOperation) actual.get(OPERATION_ID);
+
+		assertNotNull(actualOperation);
+		assertEquals(expectedOperation.getIdShort(), actualOperation.getIdShort());
+	}
+
+	@Override
+	protected ConnectedSubmodel getSubmodel() {
+		return submodel;
+	}
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/TestConnectedSubmodelElementCollection.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/TestConnectedSubmodelElementCollection.java
index 62f15ad..9dfc2d6 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/TestConnectedSubmodelElementCollection.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/TestConnectedSubmodelElementCollection.java
@@ -1,18 +1,36 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.submodel.metamodel.connected;
 
 import static org.junit.Assert.assertEquals;
 
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
 import java.util.Map;
 
-import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElementCollection;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
+import org.eclipse.basyx.submodel.metamodel.api.qualifier.haskind.ModelingKind;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
 import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
 import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperation;
 import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.ConnectedSubmodelElementCollection;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation;
-import org.eclipse.basyx.submodel.restapi.SubmodelElementCollectionProvider;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.OperationVariable;
+import org.eclipse.basyx.submodel.restapi.SubmodelProvider;
 import org.eclipse.basyx.testsuite.regression.vab.manager.VABConnectionManagerStub;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
 import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaProvider;
 import org.eclipse.basyx.vab.support.TypeDestroyer;
 import org.junit.Before;
@@ -29,7 +47,7 @@
 	private static final String PROP = "prop";
 	private static final String OPERATION = "sum";
 
-	ISubmodelElementCollection prop;
+	ConnectedSubmodelElementCollection prop;
 
 	@Before 
 	public void build() {
@@ -41,21 +59,36 @@
 		Operation operation = new Operation(arr -> {
 			return (int) arr[0] + (int) arr[1];
 		});
+		Property aProp = new Property("a", 1);
+		aProp.setModelingKind(ModelingKind.TEMPLATE);
+		Property bProp = new Property("b", 2);
+		bProp.setModelingKind(ModelingKind.TEMPLATE);
+		Property rProp = new Property("r", 3);
+		rProp.setModelingKind(ModelingKind.TEMPLATE);
+		OperationVariable a = new OperationVariable(aProp);
+		OperationVariable b = new OperationVariable(bProp);
+		OperationVariable r = new OperationVariable(rProp);
+		operation.setInputVariables(Arrays.asList(a, b));
+		operation.setOutputVariables(Collections.singletonList(r));
 		operation.setIdShort(OPERATION);
 
 		// Create ComplexDataProperty containing the created operation and property
-		SubmodelElementCollection complex = new SubmodelElementCollection();
-		complex.addElement(propertyMeta);
-		complex.addElement(operation);
+		SubmodelElementCollection complex = new SubmodelElementCollection("SubmodelCollectionId");
+		complex.addSubmodelElement(propertyMeta);
+		complex.addSubmodelElement(operation);
+		complex.setIdShort("CollectionId");
 
-		Map<String, Object> destroyType = TypeDestroyer.destroyType(complex);
+		Submodel sm = new Submodel("submodelId", new ModelUrn("testUrn"));
+		sm.addSubmodelElement(complex);
+
+		Map<String, Object> destroyType = TypeDestroyer.destroyType(sm);
 		// Create a dummy connection manager containing the created ContainerProperty map
 		// The model is wrapped in the corresponding ModelProvider that implements the API access
 		VABConnectionManagerStub manager = new VABConnectionManagerStub(
-				new SubmodelElementCollectionProvider(new VABLambdaProvider(destroyType)));
+				new SubmodelProvider(new VABLambdaProvider(destroyType)));
 
 		// Retrieve the ConnectedContainerProperty
-		prop = new ConnectedSubmodelElementCollection(manager.connectToVABElement(""));
+		prop = new ConnectedSubmodelElementCollection(manager.connectToVABElement("").getDeepProxy("/submodel/submodelElements/" + complex.getIdShort()));
 	}
 
 	/**
@@ -75,7 +108,7 @@
 		IProperty prop = props.get(PROP);
 
 		// Check contained values
-		assertEquals(4, prop.get());
+		assertEquals(4, prop.getValue());
 	}
 
 	/**
@@ -95,4 +128,43 @@
 		// Check operation invocation
 		assertEquals(5, sum.invoke(2, 3));
 	}
+	
+	@Test
+	public void testSetValue() {
+		Property property = new Property("testProperty");
+		property.setIdShort(PROP);
+		
+		
+		Collection<ISubmodelElement> newValue = new ArrayList<>();
+		newValue.add(property);
+		
+		prop.setValue(newValue);
+		
+		Map<String, ISubmodelElement> value = prop.getSubmodelElements();
+		IProperty property2 = (IProperty) value.get(PROP);
+		
+		assertEquals("testProperty", property2.getValue());
+	}
+
+	@Test
+	public void testGetSubmodelElement() {
+		ISubmodelElement element = prop.getSubmodelElement(PROP);
+		assertEquals(PROP, element.getIdShort());
+	}
+	
+	@Test(expected = ResourceNotFoundException.class)
+	public void testDeleteSubmodelElement() {
+		prop.deleteSubmodelElement(PROP);
+		prop.getSubmodelElement(PROP);
+	}
+	
+	@Test
+	public void testAddSubmodelElement() {
+		String newId = "abc";
+		Property newProp = new Property(6);
+		newProp.setIdShort(newId);
+		prop.addSubmodelElement(newProp);
+		ISubmodelElement element = prop.getSubmodelElement(newId);
+		assertEquals(newId, element.getIdShort());
+	}
 }
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/TestConnectedSubmodelElementFactory.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/TestConnectedSubmodelElementFactory.java
index 9bb6631..0cdb7b9 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/TestConnectedSubmodelElementFactory.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/TestConnectedSubmodelElementFactory.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.submodel.metamodel.connected.submodelelement;
 
 import static org.junit.Assert.assertEquals;
@@ -20,19 +29,19 @@
 import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.event.ConnectedBasicEvent;
 import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.operation.ConnectedOperation;
 import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.relationship.ConnectedRelationshipElement;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.Blob;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.File;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.MultiLanguageProperty;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.Range;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.ReferenceElement;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.range.Range;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.event.BasicEvent;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.relationship.RelationshipElement;
-import org.eclipse.basyx.submodel.restapi.SubModelProvider;
-import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
+import org.eclipse.basyx.submodel.restapi.SubmodelProvider;
+import org.eclipse.basyx.submodel.restapi.MultiSubmodelElementProvider;
 import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
 import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaProvider;
 import org.eclipse.basyx.vab.support.TypeDestroyingProvider;
@@ -76,11 +85,9 @@
 		
 		Map<String, Object> values = new HashMap<>();
 		
-		values.put(SubmodelElementProvider.PROPERTIES, dataElements);
-		values.put(SubmodelElementProvider.OPERATIONS, operations);
-		values.put(SubModel.SUBMODELELEMENT, submodelElements);
+		values.put(Submodel.SUBMODELELEMENT, submodelElements);
 		
-		proxy = new VABElementProxy("", new SubModelProvider(new TypeDestroyingProvider(new VABLambdaProvider(values))));
+		proxy = new VABElementProxy("", new SubmodelProvider(new TypeDestroyingProvider(new VABLambdaProvider(values))));
 	}
 	
 	/**
@@ -161,7 +168,7 @@
 	public void testGetProperties() {
 		Map<String, IProperty> properties =
 				ConnectedSubmodelElementFactory.getProperties(
-						proxy, SubmodelElementProvider.PROPERTIES, SubmodelElementProvider.PROPERTIES);
+						proxy, MultiSubmodelElementProvider.ELEMENTS, MultiSubmodelElementProvider.ELEMENTS);
 		
 		assertEquals(1, properties.size());
 		assertTrue(properties.get(PROPERTY_ID) instanceof ConnectedProperty);
@@ -174,7 +181,7 @@
 	public void testGetOperations() {
 		Map<String, IOperation> operations =
 				ConnectedSubmodelElementFactory.getOperations(
-						proxy, SubmodelElementProvider.OPERATIONS, SubmodelElementProvider.OPERATIONS);
+						proxy, MultiSubmodelElementProvider.ELEMENTS, MultiSubmodelElementProvider.ELEMENTS);
 		
 		assertEquals(1, operations.size());
 		assertTrue(operations.get(OPERATION_ID) instanceof ConnectedOperation);
@@ -187,7 +194,7 @@
 	public void testGetSubmodelElements() {
 		Map<String, ISubmodelElement> submodelElements =
 				ConnectedSubmodelElementFactory.getConnectedSubmodelElements(
-						proxy, SubModel.SUBMODELELEMENT, SubModel.SUBMODELELEMENT);
+						proxy, Submodel.SUBMODELELEMENT, Submodel.SUBMODELELEMENT);
 		
 		assertEquals(10, submodelElements.size());
 		assertTrue(submodelElements.get(PROPERTY_ID) instanceof ConnectedProperty);
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/dataelement/TestConnectedBlob.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/dataelement/TestConnectedBlob.java
index e6866ba..425f108 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/dataelement/TestConnectedBlob.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/dataelement/TestConnectedBlob.java
@@ -1,14 +1,23 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.submodel.metamodel.connected.submodelelement.dataelement;
 
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
 
-import java.util.Arrays;
+import java.nio.charset.StandardCharsets;
+import java.util.Base64;
 
 import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.dataelement.ConnectedBlob;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.Blob;
-import org.eclipse.basyx.submodel.restapi.PropertyProvider;
+import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
 import org.eclipse.basyx.testsuite.regression.vab.manager.VABConnectionManagerStub;
 import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaProvider;
 import org.eclipse.basyx.vab.support.TypeDestroyingProvider;
@@ -22,18 +31,19 @@
  *
  */
 public class TestConnectedBlob {
+	public final String BLOB_CONTENT = "BLOB_VALUE";
 
-	ConnectedBlob connectedBlob;
-	Blob blob;
+	protected ConnectedBlob connectedBlob;
+	protected Blob blob;
 	
 	@Before
 	public void build() {
-		blob = new Blob();
-		blob.setValue("BLOB_VALUE".getBytes());
-		blob.setMimeType("mimeType");
+		blob = new Blob("testIdShort", "mimeType");
+		byte[] value = BLOB_CONTENT.getBytes(StandardCharsets.UTF_8);
+		blob.setByteArrayValue(value);
 		
 		VABConnectionManagerStub manager = new VABConnectionManagerStub(
-				new PropertyProvider(new TypeDestroyingProvider(new VABLambdaProvider(blob))));
+				new SubmodelElementProvider(new TypeDestroyingProvider(new VABLambdaProvider(blob))));
 
 		connectedBlob = new ConnectedBlob(manager.connectToVABElement(""));
 	}
@@ -43,8 +53,19 @@
 	 */
 	@Test
 	public void testGetValue() {
-		assertTrue(Arrays.equals(blob.getValue(), connectedBlob.getValue()));
-		assertArrayEquals(blob.getValue(), connectedBlob.getValue());
+		assertEquals(blob.getValue(), connectedBlob.getValue());
+		byte[] byteArray = BLOB_CONTENT.getBytes(StandardCharsets.UTF_8);
+		assertEquals(Base64.getEncoder().encodeToString(byteArray), blob.getValue());
+
+	}
+
+	/**
+	 * Tests if getByteArrayValue() returns the correct value
+	 */
+	@Test
+	public void testGetByteArrayValue() {
+		assertArrayEquals(blob.getByteArrayValue(), connectedBlob.getByteArrayValue());
+		assertArrayEquals(BLOB_CONTENT.getBytes(StandardCharsets.UTF_8), connectedBlob.getByteArrayValue());
 	}
 	
 	/**
@@ -55,4 +76,43 @@
 		assertEquals(blob.getMimeType(), connectedBlob.getMimeType());
 	}
 	
+	/**
+	 * Tests if getUTF8String() returns the correct value
+	 */
+	@Test
+	public void testGetUTF8() {
+		assertEquals(BLOB_CONTENT, connectedBlob.getUTF8String());
+	}
+
+	/**
+	 * Tests if SetUTF8 sets the correct value
+	 */
+	@Test
+	public void testSetUTF8() {
+		connectedBlob.setUTF8String("NEW");
+		assertEquals("NEW", connectedBlob.getUTF8String());
+		assertArrayEquals("NEW".getBytes(StandardCharsets.UTF_8), connectedBlob.getByteArrayValue());
+	}
+
+	/**
+	 * Tests if SetByteArrayValue sets the correct value
+	 */
+	@Test
+	public void testSetByteArray() {
+		byte[] newArrayValue = "NEW".getBytes(StandardCharsets.UTF_8);
+		connectedBlob.setByteArrayValue(newArrayValue);
+		assertEquals("NEW", connectedBlob.getUTF8String());
+		assertArrayEquals("NEW".getBytes(StandardCharsets.UTF_8), connectedBlob.getByteArrayValue());
+	}
+
+	/**
+	 * Tests if setValue sets the correct value
+	 */
+	@Test
+	public void testSetValue() {
+		byte[] newArrayValue = "NEW".getBytes(StandardCharsets.UTF_8);
+		String newStringValue = Base64.getEncoder().encodeToString(newArrayValue);
+		connectedBlob.setValue(newStringValue);
+		assertEquals("NEW", connectedBlob.getUTF8String());
+	}
 }
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/dataelement/TestConnectedFile.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/dataelement/TestConnectedFile.java
index a4e7e25..da0a241 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/dataelement/TestConnectedFile.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/dataelement/TestConnectedFile.java
@@ -1,10 +1,19 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.submodel.metamodel.connected.submodelelement.dataelement;
 
 import static org.junit.Assert.assertEquals;
 
 import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.dataelement.ConnectedFile;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.File;
-import org.eclipse.basyx.submodel.restapi.PropertyProvider;
+import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
 import org.eclipse.basyx.testsuite.regression.vab.manager.VABConnectionManagerStub;
 import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaProvider;
 import org.eclipse.basyx.vab.support.TypeDestroyingProvider;
@@ -25,11 +34,12 @@
 	@Before
 	public void build() {
 		file = new File();
+		file.setIdShort("testIdShort");
 		file.setValue("FILE_VALUE");
 		file.setMimeType("mimeType");
 		
 		VABConnectionManagerStub manager = new VABConnectionManagerStub(
-				new PropertyProvider(new TypeDestroyingProvider(new VABLambdaProvider(file))));
+				new SubmodelElementProvider(new TypeDestroyingProvider(new VABLambdaProvider(file))));
 
 		connectedFile = new ConnectedFile(manager.connectToVABElement(""));
 	}
@@ -50,4 +60,12 @@
 		assertEquals(file.getMimeType(), connectedFile.getMimeType());
 	}
 	
+	@Test
+	public void testSetValue() {
+		String value = connectedFile.getValue();
+		value += "TEST";
+		connectedFile.setValue(value);
+		assertEquals(value, connectedFile.getValue());
+	}
+	
 }
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/dataelement/TestConnectedMultiLanguageProperty.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/dataelement/TestConnectedMultiLanguageProperty.java
index 5b53146..8e45751 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/dataelement/TestConnectedMultiLanguageProperty.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/dataelement/TestConnectedMultiLanguageProperty.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.submodel.metamodel.connected.submodelelement.dataelement;
 
 import static org.junit.Assert.assertEquals;
@@ -9,7 +18,7 @@
 import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
 import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.MultiLanguageProperty;
-import org.eclipse.basyx.submodel.restapi.PropertyProvider;
+import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
 import org.eclipse.basyx.testsuite.regression.vab.manager.VABConnectionManagerStub;
 import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaProvider;
 import org.eclipse.basyx.vab.support.TypeDestroyingProvider;
@@ -36,7 +45,7 @@
 		MLP = new MultiLanguageProperty(ref, langStrings);
 		
 		VABConnectionManagerStub manager = new VABConnectionManagerStub(
-				new PropertyProvider(new TypeDestroyingProvider(new VABLambdaProvider(MLP))));
+				new SubmodelElementProvider(new TypeDestroyingProvider(new VABLambdaProvider(MLP))));
 
 		// Retrieve the ConnectedContainerProperty
 		connectedMLP = new ConnectedMultiLanguageProperty(manager.connectToVABElement(""));
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/dataelement/TestConnectedRange.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/dataelement/TestConnectedRange.java
index e83a023..db88e50 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/dataelement/TestConnectedRange.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/dataelement/TestConnectedRange.java
@@ -1,10 +1,21 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.submodel.metamodel.connected.submodelelement.dataelement;
 
 import static org.junit.Assert.assertEquals;
 
 import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.dataelement.ConnectedRange;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.Range;
-import org.eclipse.basyx.submodel.restapi.PropertyProvider;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.range.Range;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.range.RangeValue;
+import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
 import org.eclipse.basyx.testsuite.regression.vab.manager.VABConnectionManagerStub;
 import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaProvider;
 import org.eclipse.basyx.vab.support.TypeDestroyingProvider;
@@ -24,10 +35,10 @@
 	
 	@Before
 	public void build() {
-		range = new Range("valueType", new Integer(1), new Integer(10));
-		
+		range = new Range(ValueType.Integer, new Integer(1), new Integer(10));
+		range.setIdShort("testIdShort");
 		VABConnectionManagerStub manager = new VABConnectionManagerStub(
-				new PropertyProvider(new TypeDestroyingProvider(new VABLambdaProvider(range))));
+				new SubmodelElementProvider(new TypeDestroyingProvider(new VABLambdaProvider(range))));
 
 		connectedRange = new ConnectedRange(manager.connectToVABElement(""));
 	}
@@ -55,4 +66,28 @@
 	public void testGetMax() {
 		assertEquals(range.getMax(), connectedRange.getMax());
 	}
+	
+	/**
+	 * Tests if getValue() returns the correct value
+	 */
+	@Test
+	public void testGetValue() {
+		RangeValue rv = connectedRange.getValue();
+		assertEquals(range.getMin(), rv.getMin());
+		assertEquals(range.getMax(), rv.getMax());
+	}
+	
+	/**
+	 * Tests if setValue() sets the correct value.
+	 */
+	@Test
+	public void testSetValue() {
+		RangeValue value = new RangeValue(2, 8);
+		
+		connectedRange.setValue(value);
+		
+		assertEquals(2, connectedRange.getMin());
+		assertEquals(8, connectedRange.getMax());
+		assertEquals(range.getValueType(), connectedRange.getValueType());
+	}
 }
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/dataelement/TestConnectedReferenceElement.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/dataelement/TestConnectedReferenceElement.java
index 562d7d8..049abc0 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/dataelement/TestConnectedReferenceElement.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/dataelement/TestConnectedReferenceElement.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.submodel.metamodel.connected.submodelelement.dataelement;
 
 import static org.junit.Assert.assertEquals;
@@ -8,7 +17,7 @@
 import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
 import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.ReferenceElement;
-import org.eclipse.basyx.submodel.restapi.PropertyProvider;
+import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
 import org.eclipse.basyx.testsuite.regression.vab.manager.VABConnectionManagerStub;
 import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaProvider;
 import org.eclipse.basyx.vab.support.TypeDestroyingProvider;
@@ -34,7 +43,7 @@
 		refElem = new ReferenceElement(ref);
 		
 		VABConnectionManagerStub manager = new VABConnectionManagerStub(
-				new PropertyProvider(new TypeDestroyingProvider(new VABLambdaProvider(refElem))));
+				new SubmodelElementProvider(new TypeDestroyingProvider(new VABLambdaProvider(refElem))));
 
 		connectedRefElem = new ConnectedReferenceElement(manager.connectToVABElement(""));
 	}
@@ -46,4 +55,4 @@
 	public void testGetValue() {
 		assertEquals(refElem.getValue(), connectedRefElem.getValue());
 	}
-}
\ No newline at end of file
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/event/TestConnectedBasicEvent.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/event/TestConnectedBasicEvent.java
index 58f8f91..ad870f5 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/event/TestConnectedBasicEvent.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/event/TestConnectedBasicEvent.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.submodel.metamodel.connected.submodelelement.event;
 
 import static org.junit.Assert.assertEquals;
@@ -8,7 +17,7 @@
 import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
 import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.event.BasicEvent;
-import org.eclipse.basyx.submodel.restapi.PropertyProvider;
+import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
 import org.eclipse.basyx.testsuite.regression.vab.manager.VABConnectionManagerStub;
 import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaProvider;
 import org.eclipse.basyx.vab.support.TypeDestroyingProvider;
@@ -34,7 +43,7 @@
 		event = new BasicEvent(ref);
 		
 		VABConnectionManagerStub manager = new VABConnectionManagerStub(
-				new PropertyProvider(new TypeDestroyingProvider(new VABLambdaProvider(event))));
+				new SubmodelElementProvider(new TypeDestroyingProvider(new VABLambdaProvider(event))));
 
 		connectedEvent = new ConnectedBasicEvent(manager.connectToVABElement(""));
 	}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/operation/TestConnectedOperation.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/operation/TestConnectedOperation.java
index ecd5f16..3674dcd 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/operation/TestConnectedOperation.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/operation/TestConnectedOperation.java
@@ -1,26 +1,25 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.submodel.metamodel.connected.submodelelement.operation;
 
-import static org.junit.Assert.assertEquals;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
 import java.util.Map;
-import java.util.function.Function;
 
 import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperation;
 import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.operation.ConnectedOperation;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetypedef.PropertyValueTypeDef;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.OperationHelper;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.OperationVariable;
 import org.eclipse.basyx.submodel.restapi.OperationProvider;
+import org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.submodelelement.operation.TestOperationSuite;
 import org.eclipse.basyx.testsuite.regression.vab.manager.VABConnectionManagerStub;
 import org.eclipse.basyx.vab.manager.VABConnectionManager;
 import org.eclipse.basyx.vab.modelprovider.map.VABMapProvider;
 import org.eclipse.basyx.vab.support.TypeDestroyer;
-import org.junit.Before;
-import org.junit.Test;
 
 /**
  * Tests if a ConnectedOperation can be created and used correctly
@@ -29,42 +28,16 @@
  * @author schnicke
  *
  */
-public class TestConnectedOperation {
+public class TestConnectedOperation extends TestOperationSuite {
 
-	IOperation operation;
-
-	@Before
-	public void build() {
-		// Create the operation map using the MetaModelElementFactory
-		Operation op = new Operation((Function<Object[], Object>) obj -> {
-			return (int) obj[0] + (int) obj[1];
-		});
-
-		List<OperationVariable> in = new ArrayList<>();
-
-		in.add(new OperationVariable(OperationHelper.createPropertyTemplate(PropertyValueTypeDef.Integer)));
-		in.add(new OperationVariable(OperationHelper.createPropertyTemplate(PropertyValueTypeDef.Integer)));
-
-		op.setInputVariables(in);
-
-		op.setOutputVariables(Collections.singletonList(new OperationVariable(OperationHelper.createPropertyTemplate(PropertyValueTypeDef.Integer))));
-
-		Map<String, Object> destroyType = TypeDestroyer.destroyType(op);
+	@Override
+	protected IOperation prepareOperation(Operation operation) {
+		Map<String, Object> destroyType = TypeDestroyer.destroyType(operation);
 		// Create a dummy connection manager containing the created Operation map
 		VABConnectionManager manager = new VABConnectionManagerStub(
 				new OperationProvider(new VABMapProvider(destroyType)));
 
 		// Create the ConnectedOperation based on the manager stub
-		operation = new ConnectedOperation(manager.connectToVABElement(""));
-	}
-
-	/**
-	 * Tests if a operation invocation is handled correctly
-	 *
-	 * @throws Exception
-	 */
-	@Test
-	public void invokeTest() throws Exception {
-		assertEquals(4, operation.invoke(2, 2));
+		return new ConnectedOperation(manager.connectToVABElement(""));
 	}
 }
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/relationship/TestConnectedAnnotatedRelationshipElement.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/relationship/TestConnectedAnnotatedRelationshipElement.java
new file mode 100644
index 0000000..a101f93
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/relationship/TestConnectedAnnotatedRelationshipElement.java
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.submodel.metamodel.connected.submodelelement.relationship;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IDataElement;
+import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.relationship.ConnectedAnnotatedRelationshipElement;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.relationship.AnnotatedRelationshipElement;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.relationship.AnnotatedRelationshipElementValue;
+import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
+import org.eclipse.basyx.testsuite.regression.vab.manager.VABConnectionManagerStub;
+import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaProvider;
+import org.eclipse.basyx.vab.support.TypeDestroyingProvider;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests if a ConnectedAnnotatedRelationshipElement can be created and used correctly
+ * 
+ * @author conradi
+ *
+ */
+public class TestConnectedAnnotatedRelationshipElement {
+
+	ConnectedAnnotatedRelationshipElement connectedElement;
+	AnnotatedRelationshipElement element;
+	
+	@Before
+	public void build() {
+		Reference ref1 = new Reference(new Key(KeyElements.BLOB, true, "1", IdentifierType.CUSTOM));
+		Reference ref2 = new Reference(new Key(KeyElements.FILE, false, "2", IdentifierType.IRDI));
+		
+		Property property = new Property("PropertyId", 10);
+		List<IDataElement> annotations = new ArrayList<>();
+		annotations.add(property);
+		
+		element = new AnnotatedRelationshipElement("testId", ref1, ref2);
+		element.setAnnotation(annotations);
+		
+		VABConnectionManagerStub manager = new VABConnectionManagerStub(
+				new SubmodelElementProvider(new TypeDestroyingProvider(new VABLambdaProvider(element))));
+
+		connectedElement = new ConnectedAnnotatedRelationshipElement(manager.connectToVABElement(""));
+	}
+	
+	/**
+	 * Tests if getValue() returns the correct value
+	 */
+	@Test
+	public void testGetValue() {
+		AnnotatedRelationshipElementValue value = connectedElement.getValue();
+		assertEquals(element.getFirst(), value.getFirst());
+		assertEquals(element.getSecond(), value.getSecond());
+		assertEquals(element.getValue().getAnnotations().size(), value.getAnnotations().size());
+	}
+	
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/relationship/TestConnectedRelationshipElement.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/relationship/TestConnectedRelationshipElement.java
index 95dd6a3..49308e7 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/relationship/TestConnectedRelationshipElement.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/relationship/TestConnectedRelationshipElement.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.submodel.metamodel.connected.submodelelement.relationship;
 
 import static org.junit.Assert.assertEquals;
@@ -8,7 +17,8 @@
 import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
 import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.relationship.RelationshipElement;
-import org.eclipse.basyx.submodel.restapi.PropertyProvider;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.relationship.RelationshipElementValue;
+import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
 import org.eclipse.basyx.testsuite.regression.vab.manager.VABConnectionManagerStub;
 import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaProvider;
 import org.eclipse.basyx.vab.support.TypeDestroyingProvider;
@@ -32,28 +42,23 @@
 		Reference ref1 = new Reference(new Key(KeyElements.BLOB, true, "1", IdentifierType.CUSTOM));
 		Reference ref2 = new Reference(new Key(KeyElements.FILE, false, "2", IdentifierType.IRDI));
 		
-		relElem = new RelationshipElement(ref1, ref2);
+		relElem = new RelationshipElement("testId", ref1, ref2);
 		
 		
 		VABConnectionManagerStub manager = new VABConnectionManagerStub(
-				new PropertyProvider(new TypeDestroyingProvider(new VABLambdaProvider(relElem))));
+				new SubmodelElementProvider(new TypeDestroyingProvider(new VABLambdaProvider(relElem))));
 
 		connectedRelElem = new ConnectedRelationshipElement(manager.connectToVABElement(""));
 	}
 
 	/**
-	 * Tests if getFirst() returns the correct value
+	 * Tests if getValue() returns the correct value
 	 */
 	@Test
-	public void testGetFirst() {
-		assertEquals(relElem.getFirst(), connectedRelElem.getFirst());
+	public void testGetValue() {
+		RelationshipElementValue value = connectedRelElem.getValue();
+		assertEquals(relElem.getFirst(), value.getFirst());
+		assertEquals(relElem.getSecond(), value.getSecond());
 	}
 
-	/**
-	 * Tests if getSecond() returns the correct value
-	 */
-	@Test
-	public void testGetSecond() {
-		assertEquals(relElem.getSecond(), connectedRelElem.getSecond());
-	}
 }
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/facade/TestSubmodelElementMapCollectionConverter.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/facade/TestSubmodelElementMapCollectionConverter.java
new file mode 100644
index 0000000..ddc55c9
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/facade/TestSubmodelElementMapCollectionConverter.java
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.submodel.metamodel.facade;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Collection;
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.facade.SubmodelElementMapCollectionConverter;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.vab.support.TypeDestroyer;
+import org.junit.Test;
+
+/**
+ * Tests for SubmodelElementMapCollectionConverter
+ * 
+ * @author conradi
+ *
+ */
+public class TestSubmodelElementMapCollectionConverter {
+
+	private static final String ID_SHORT = "testElement";
+
+
+	@Test
+	public void testMapToSM() {
+		Submodel sm = getSM();
+		
+		// Replace the smElement Map with a Collection
+		sm.put(Submodel.SUBMODELELEMENT, sm.getSubmodelElements().values());
+		
+		// Make a Map from the SM, as if it was transferred over the VAB
+		Map<String, Object> map = TypeDestroyer.destroyType(sm);
+		
+		
+		sm = SubmodelElementMapCollectionConverter.mapToSM(map);
+		
+		assertTrue(sm.get(Submodel.SUBMODELELEMENT) instanceof Map<?, ?>);
+		
+		assertNotNull(sm.getSubmodelElements().get(ID_SHORT));
+		assertTrue(sm.getSubmodelElements().get(ID_SHORT) instanceof Property);
+	}
+	
+	@SuppressWarnings("unchecked")
+	@Test
+	public void testSMToMap() {
+		Submodel sm = getSM();
+		
+		Map<String, Object> map = SubmodelElementMapCollectionConverter.smToMap(sm);
+		
+		assertTrue(map.get(Submodel.SUBMODELELEMENT) instanceof Collection<?>);
+		assertEquals(1, ((Collection<ISubmodelElement>) map.get(Submodel.SUBMODELELEMENT)).size());
+	}
+
+
+	private Submodel getSM() {
+		Submodel sm = new Submodel("submodelIdShort", new ModelUrn("submodelUrn"));
+		Property property = new Property(ID_SHORT, ValueType.String);
+		
+		sm.addSubmodelElement(property);
+		return sm;
+	}
+	
+	
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/TestSubmodel.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/TestSubmodel.java
index e287d2f..4b6ae58 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/TestSubmodel.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/TestSubmodel.java
@@ -1,72 +1,64 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 
-import java.util.ArrayList;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.Map;
 
+import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
+import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
 import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
-import org.eclipse.basyx.submodel.metamodel.api.qualifier.haskind.ModelingKind;
 import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
-import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
-import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasDataSpecification;
-import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasSemantics;
-import org.eclipse.basyx.submodel.metamodel.map.qualifier.Identifiable;
-import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangStrings;
-import org.eclipse.basyx.submodel.metamodel.map.qualifier.haskind.HasKind;
-import org.eclipse.basyx.submodel.metamodel.map.qualifier.qualifiable.Formula;
-import org.eclipse.basyx.submodel.metamodel.map.qualifier.qualifiable.Qualifiable;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
 import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
 import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.testsuite.regression.submodel.metamodel.TestSubmodelSuite;
+import org.junit.Before;
 import org.junit.Test;
 
 /**
- * Ensures correct behavior of {@link SubModel}
+ * Ensures correct behavior of {@link Submodel}
  * 
  * @author haque
  *
  */
-public class TestSubmodel {
-	
+public class TestSubmodel extends TestSubmodelSuite {
+
+	ISubmodel submodel;
+
+	@Before
+	public void build() {
+		submodel = getReferenceSubmodel();
+	}
+
 	@Test
-	public void testAddSubmodelElement() {
-		String submodelId = "submodelID";
-		String identifierId = "testId";
-		String propId = "propertyID";
-		
-		HasSemantics semantics = new HasSemantics(new Reference(new Key(KeyElements.ASSET, true, "testValue", IdentifierType.IRDI)));
-		Identifiable identifiable = new Identifiable("1", "5", submodelId, "testCategory", new LangStrings("DE", "test"), IdentifierType.IRDI, identifierId);
-		Qualifiable qualifiable = new Qualifiable(new Formula(Collections.singleton(new Reference(new Key(KeyElements.BLOB, true, "TestValue", IdentifierType.IRI)))));
-		HasDataSpecification specification = new HasDataSpecification(new ArrayList<>(), Collections.singleton(new Reference(new Key(KeyElements.BLOB, true, "testRef", IdentifierType.IRI))));
-		HasKind hasKind = new HasKind(ModelingKind.INSTANCE);
-		
-		// Create a submodel 
-		SubModel subModel = new SubModel(semantics, identifiable, qualifiable, specification, hasKind);
-		
-		//Create a submodel element and set an id to it
-		Property property = new Property("testValue");
-		property.setIdShort(propId);
-		
-		// Add the element to the submodel
-		subModel.addSubModelElement(property);
-		
-		// Create expected map of added submodel element for assertion
-		Map<String, ISubmodelElement> submodelElemMap = new HashMap<String, ISubmodelElement>();
-		submodelElemMap.put(propId, property);
-		assertEquals(submodelElemMap, subModel.getSubmodelElements());
+	public void testParentAddSubmodelElement() {
+		Property prop = new Property("propIdShort", ValueType.String);
+		IIdentifier identifier = new ModelUrn("testId");
+		Submodel submodel = new Submodel("smIdShort", identifier);
+		submodel.addSubmodelElement(prop);
 		
 		// Create expected parent of the element for assertion
-		Reference expectedParent = new Reference(new Key(KeyElements.SUBMODEL, true, identifierId, IdentifierType.IRDI));
-		assertEquals(expectedParent, property.getParent());
+		Reference expectedParent = new Reference(new Key(KeyElements.SUBMODEL, true, identifier.getId(), identifier.getIdType()));
+		assertEquals(expectedParent, prop.getParent());
 	} 
 
 	/**
-	 * Tests if a SubModel containing a list for SUBMODELELEMENT is correctly
+	 * Tests if a Submodel containing a list for SUBMODELELEMENT is correctly
 	 * handled by the facading submodel. This is necessary because the submodel
 	 * serialization does specify SUBMODELELEMENT as list
 	 */
@@ -79,12 +71,18 @@
 		expected.setIdShort(propId);
 
 		// Create test submodel and force key SUBMODELELEMENT to contain a list
-		SubModel sm = new SubModel();
-		sm.put(SubModel.SUBMODELELEMENT, Collections.singleton(expected));
+		String id = "testIdShort";
+		Submodel sm = new Submodel(id, new Identifier(IdentifierType.IRDI, id));
+		sm.put(Submodel.SUBMODELELEMENT, Collections.singleton(expected));
 
 		// Check if the facade converts the SUBMODELELEMENT value correctly
-		SubModel facade = SubModel.createAsFacade(sm);
-		assertTrue(facade.get(SubModel.SUBMODELELEMENT) instanceof Map<?, ?>);
+		Submodel facade = Submodel.createAsFacade(sm);
+		assertTrue(facade.get(Submodel.SUBMODELELEMENT) instanceof Map<?, ?>);
 		assertEquals(expected, facade.getSubmodelElements().get(propId));
 	}
+
+	@Override
+	protected ISubmodel getSubmodel() {
+		return submodel;
+	}
 }
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/dataspecification/TestDataSpecificationIEC61360.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/dataspecification/TestDataSpecificationIEC61360.java
index 196a755..b001dc4 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/dataspecification/TestDataSpecificationIEC61360.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/dataspecification/TestDataSpecificationIEC61360.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.dataspecification;
 
 import static org.junit.Assert.assertEquals;
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/dataspecification/TestEmbeddedDataSpecification.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/dataspecification/TestEmbeddedDataSpecification.java
index 9cac7a6..24bdb99 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/dataspecification/TestEmbeddedDataSpecification.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/dataspecification/TestEmbeddedDataSpecification.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.dataspecification;
 
 import static org.junit.Assert.assertEquals;
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/dataspecification/TestValueReferencePair.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/dataspecification/TestValueReferencePair.java
index 9267004..b0e84f1 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/dataspecification/TestValueReferencePair.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/dataspecification/TestValueReferencePair.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.dataspecification;
 
 import static org.junit.Assert.assertEquals;
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/identifier/TestIdentifier.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/identifier/TestIdentifier.java
index c7c8584..c1e1165 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/identifier/TestIdentifier.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/identifier/TestIdentifier.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.identifier;
 
 import static org.junit.Assert.assertEquals;
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/modeltype/TestModelType.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/modeltype/TestModelType.java
index b927f1c..71c22a9 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/modeltype/TestModelType.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/modeltype/TestModelType.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.modeltype;
 
 import static org.junit.Assert.assertEquals;
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/parts/TestConceptDescription.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/parts/TestConceptDescription.java
index 6eee6dc..1592000 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/parts/TestConceptDescription.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/parts/TestConceptDescription.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.parts;
 
 import static org.junit.Assert.assertEquals;
@@ -40,7 +49,7 @@
 	
 	@Before
 	public void buildConceptDescription() {
-		description = new ConceptDescription();
+		description = new ConceptDescription("testConceptDescriptionID", new Identifier(IdentifierType.IRDI,  "testId"));
 	}
 	
 	@Test
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestAdministrativeInformation.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestAdministrativeInformation.java
index e7a21ba..64315ed 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestAdministrativeInformation.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestAdministrativeInformation.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.qualifier;
 
 import static org.junit.Assert.assertEquals;
@@ -56,16 +65,34 @@
 	}
 	
 	@Test
-	public void testSetVersion() {
+	public void testSetVersionInformation() {
 		String newVersionString = "2.0";
-		information.setVersion(newVersionString);
+		String newRevisionString = "2.0.1";
+		information.setVersionInformation(newVersionString, newRevisionString);
 		assertEquals(newVersionString, information.getVersion());
+		assertEquals(newRevisionString, information.getRevision());
+	}
+	
+	@Test(expected = RuntimeException.class)
+	public void testSetVersionInformationExceptionEmptyString() {
+		String newVersionString = "";
+		String newRevisionString = "2.0.1";
+		information.setVersionInformation(newVersionString, newRevisionString);
+	}
+	
+	@Test(expected = RuntimeException.class)
+	public void testSetVersionInformationExceptionNullString() {
+		String newVersionString = null;
+		String newRevisionString = "2.0.1";
+		information.setVersionInformation(newVersionString, newRevisionString);
 	}
 	
 	@Test
-	public void testSetRevision() {
-		String newRevisionString = "2.0.1";
-		information.setRevision(newRevisionString);
+	public void testSetVersionInformationNoRevision() {
+		String newVersionString = "";
+		String newRevisionString = "";
+		information.setVersionInformation(newVersionString, newRevisionString);
+		assertEquals(newVersionString, information.getVersion());
 		assertEquals(newRevisionString, information.getRevision());
 	}
 	
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestHasDataSpecification.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestHasDataSpecification.java
index 0ed4b74..6c4128c 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestHasDataSpecification.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestHasDataSpecification.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.qualifier;
 
 import static org.junit.Assert.assertEquals;
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestHasSemantics.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestHasSemantics.java
index 01d8861..2d753ff 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestHasSemantics.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestHasSemantics.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.qualifier;
 
 import static org.junit.Assert.assertEquals;
@@ -45,7 +54,7 @@
 		KeyElements keyElements = KeyElements.BLOB;
 		boolean isLocal = true;
 		Reference reference = new Reference(identifier, keyElements, isLocal);
-		semantics.setSemanticID(reference);
+		semantics.setSemanticId(reference);
 		assertEquals(reference, semantics.getSemanticId());
 	}
 }
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestIdentifiable.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestIdentifiable.java
index 34f842e..3206a38 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestIdentifiable.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestIdentifiable.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.qualifier;
 
 import static org.junit.Assert.assertEquals;
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestLangString.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestLangString.java
index 5fef18d..d5d36b6 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestLangString.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestLangString.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.qualifier;
 
 import static org.junit.Assert.assertEquals;
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestLangStrings.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestLangStrings.java
index 5f02fb9..5a6fd7e 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestLangStrings.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestLangStrings.java
@@ -1,6 +1,17 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.qualifier;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 
 import java.util.ArrayList;
 import java.util.Collection;
@@ -75,4 +86,18 @@
 		assertEquals(languageSet, langStrings.getLanguages());
 	}
 	
+	@Test
+	public void testIsLangStrings() {
+		LangStrings langStrings = new LangStrings(LANGUAGE1, TEXT1);
+		
+		assertTrue(LangStrings.isLangStrings(langStrings));
+		
+		LangString langString = new LangString(LANGUAGE1, TEXT1);
+		langString.put("language", null);
+		
+		langStrings.add(langString);
+		
+		assertFalse(LangStrings.isLangStrings(langStrings));
+	}
+	
 }
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestReferable.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestReferable.java
index efa1b8a..d16211c 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestReferable.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestReferable.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.qualifier;
 
 import static org.junit.Assert.assertEquals;
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/haskind/TestHasKind.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/haskind/TestHasKind.java
index 711b21f..f2f79b2 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/haskind/TestHasKind.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/haskind/TestHasKind.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.qualifier.haskind;
 
 import static org.junit.Assert.assertEquals;
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/qualifiable/TestFormula.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/qualifiable/TestFormula.java
index 016cc51..e2bd682 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/qualifiable/TestFormula.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/qualifiable/TestFormula.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.qualifier.qualifiable;
 
 import static org.junit.Assert.assertEquals;
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/qualifiable/TestQualifiable.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/qualifiable/TestQualifiable.java
index 38da65f..0ad6c11 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/qualifiable/TestQualifiable.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/qualifiable/TestQualifiable.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.qualifier.qualifiable;
 
 import static org.junit.Assert.assertEquals;
@@ -29,7 +38,7 @@
 	@Test
 	public void testConstructor1() {
 		Qualifiable qualifiable = new Qualifiable(FORMULA1);
-		assertEquals(Collections.singleton(FORMULA1), qualifiable.getQualifier());
+		assertEquals(Collections.singleton(FORMULA1), qualifiable.getQualifiers());
 	}
 	
 	@Test
@@ -39,14 +48,14 @@
 		constraints.add(FORMULA2);
 		
 		Qualifiable qualifiable = new Qualifiable(constraints);
-		assertEquals(constraints, qualifiable.getQualifier());
+		assertEquals(constraints, qualifiable.getQualifiers());
 	}
 	
 	@Test
 	public void testSetQualifier() {
 		Qualifiable qualifiable = new Qualifiable(FORMULA1);
 		
-		qualifiable.setQualifier(Collections.singleton(FORMULA2));
-		assertEquals(Collections.singleton(FORMULA2), qualifiable.getQualifier());
+		qualifiable.setQualifiers(Collections.singleton(FORMULA2));
+		assertEquals(Collections.singleton(FORMULA2), qualifiable.getQualifiers());
 	}
 }
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/qualifiable/TestQualifier.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/qualifiable/TestQualifier.java
index 7f62e34..3b9cbad 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/qualifiable/TestQualifier.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/qualifiable/TestQualifier.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.qualifier.qualifiable;
 
 import static org.junit.Assert.assertEquals;
@@ -7,6 +16,8 @@
 import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
 import org.eclipse.basyx.submodel.metamodel.map.qualifier.qualifiable.Qualifier;
 import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueTypeHelper;
 import org.junit.Before;
 import org.junit.Test;
 
@@ -22,7 +33,7 @@
 	private static final boolean IS_LOCAL = false;
 	private static final String VALUE = "testValue";
 	private static final String TYPE = "testType";
-	private static final String VALUE_TYPE = "testValueType";
+	private static final String VALUE_TYPE = "anyType";
 	private static final IdentifierType ID_TYPE = IdentifierType.CUSTOM;
 	private static final Identifier IDENTIFIER = new Identifier(ID_TYPE, VALUE);
 	private static final Reference VALUE_ID = new Reference(IDENTIFIER, KEY_ELEMENTS, IS_LOCAL);
@@ -38,7 +49,7 @@
 	public void testConstructor() {
 		assertEquals(TYPE, qualifier.getType());
 		assertEquals(VALUE, qualifier.getValue());
-		assertEquals(VALUE_TYPE, qualifier.getValueType());
+		assertEquals(ValueTypeHelper.fromName(VALUE_TYPE), qualifier.getValueType());
 		assertEquals(VALUE_ID, qualifier.getValueId());
 	}
 	
@@ -65,15 +76,23 @@
 	
 	@Test
 	public void testSetValueType() {
-		String newValueTypeString = "newValueType";
+		ValueType newValueTypeString = ValueType.AnyType;
 		qualifier.setValueType(newValueTypeString);
 		assertEquals(newValueTypeString, qualifier.getValueType());
 	}
 	
+	// Tests if the valueType is correctly converted to a string
+	@Test
+	public void testSetValueCorrectValueType() {
+		Qualifier emptyQualifier = new Qualifier();
+		emptyQualifier.setValue("Test");
+		assertEquals(ValueType.String.toString(), emptyQualifier.get(Qualifier.VALUETYPE));
+	}
+
 	@Test
 	public void testSetSemanticID() {
 		Reference reference = new Reference(new Identifier(IdentifierType.IRI, "newId"), KeyElements.BLOB, true);
-		qualifier.setSemanticID(reference);
+		qualifier.setSemanticId(reference);
 		assertEquals(reference, qualifier.getSemanticId());
 	}
 }
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/reference/TestKey.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/reference/TestKey.java
index 7039b7c..a274010 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/reference/TestKey.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/reference/TestKey.java
@@ -1,6 +1,16 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.reference;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 
@@ -83,4 +93,13 @@
 		key.setIdType(type);
 		assertEquals(type, key.getIdType());
 	}
+	
+	@Test
+	public void testIsKey() {
+		assertTrue(Key.isKey(key));
+		
+		key.put(Key.IDTYPE, "nonsense");
+		
+		assertFalse(Key.isKey(key));
+	}
 }
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/reference/TestReference.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/reference/TestReference.java
index 4ec0377..4f37231 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/reference/TestReference.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/reference/TestReference.java
@@ -1,6 +1,17 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.reference;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 
 import java.util.ArrayList;
 import java.util.Collection;
@@ -77,4 +88,16 @@
  		reference.setKeys(keysList);
 		assertEquals(keysList, reference.getKeys());
 	}
+	
+	@Test
+	public void testIsReference() {
+		Identifiable identifiable = new Identifiable("2.0", "5", "testIDShort", "testCategory", new LangStrings("Eng", "test"), IdentifierType.IRI, "newId");
+		Reference reference = new Reference(identifiable, KEY_ELEMENTS, IS_LOCAL);
+		
+		assertTrue(Reference.isReference(reference));
+		
+		reference.put(Reference.KEY, "nonsense");
+		
+		assertFalse(Reference.isReference(reference));
+	}
 }
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/TestSubmodelElement.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/TestSubmodelElement.java
new file mode 100644
index 0000000..0898ed9
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/TestSubmodelElement.java
@@ -0,0 +1,111 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.submodelelement;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Collection;
+import java.util.Collections;
+
+import org.eclipse.basyx.submodel.metamodel.api.dataspecification.IEmbeddedDataSpecification;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.api.qualifier.haskind.ModelingKind;
+import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
+import org.eclipse.basyx.submodel.metamodel.map.dataspecification.EmbeddedDataSpecification;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangStrings;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.qualifiable.Formula;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests constructor and getter of {@link SubmodelElement} for their
+ * correctness
+ * 
+ * @author haque
+ *
+ */
+public class TestSubmodelElement {
+	private static final Reference REFERENCE = new Reference(new Identifier(IdentifierType.CUSTOM, "testValue"), KeyElements.ACCESSPERMISSIONRULE, false);
+	private static final Formula FORMULA = new Formula(Collections.singleton(new Reference(new Key(KeyElements.BLOB, true, "TestValue", IdentifierType.IRI))));
+	
+	private SubmodelElement submodelElement;
+	
+	@Before
+	public void buidSubmodelElement() {
+		submodelElement = new Property("testIdShort", "testId");
+	}
+	
+	@Test
+	public void testSetDataSpecificationReferences() {
+		Collection<IReference> refs = Collections.singleton(REFERENCE);
+		submodelElement.setDataSpecificationReferences(refs);
+		assertEquals(refs, submodelElement.getDataSpecificationReferences());
+	} 
+	
+	@Test
+	public void testSetEmbeddedDataSpecifications() {
+		EmbeddedDataSpecification embeddedDataSpecification = new EmbeddedDataSpecification();
+		Collection<IEmbeddedDataSpecification> specifications = Collections.singleton(embeddedDataSpecification);
+		submodelElement.setEmbeddedDataSpecifications(specifications);
+		assertEquals(specifications, submodelElement.getEmbeddedDataSpecifications());
+	}
+	
+	@Test
+	public void testSetIdShort() {
+		String newIdString = "newId";
+		submodelElement.setIdShort(newIdString);
+		assertEquals(newIdString, submodelElement.getIdShort());
+	}
+	
+	@Test
+	public void testSetCategory() {
+		String newCategoryString = "newCategory";
+		submodelElement.setCategory(newCategoryString);
+		assertEquals(newCategoryString, submodelElement.getCategory());
+	}
+	
+	@Test
+	public void testSetDescription() {
+		LangStrings newDescriptionString = new LangStrings("DE", "newTest");
+		submodelElement.setDescription(newDescriptionString);
+		assertEquals(newDescriptionString, submodelElement.getDescription());
+	}
+	
+	@Test
+	public void testSetParent() {
+		submodelElement.setParent(REFERENCE);
+		assertEquals(REFERENCE, submodelElement.getParent());
+	}
+	
+	@Test
+	public void testSetQualifier() {
+		submodelElement.setQualifiers(Collections.singleton(FORMULA));
+		assertEquals(Collections.singleton(FORMULA), submodelElement.getQualifiers());
+	}
+	
+	@Test
+	public void testSetSemanticID() {
+		submodelElement.setSemanticId(REFERENCE);
+		assertEquals(REFERENCE, submodelElement.getSemanticId());
+	}
+	
+	@Test
+	public void testSetModelingKind() {
+		ModelingKind newModelingKind = ModelingKind.TEMPLATE;
+		submodelElement.setModelingKind(newModelingKind);
+		assertEquals(newModelingKind, submodelElement.getModelingKind());
+	}
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/TestSubmodelElementCollection.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/TestSubmodelElementCollection.java
index 6d24f0d..2721243 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/TestSubmodelElementCollection.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/TestSubmodelElementCollection.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.submodelelement;
 
 import static org.junit.Assert.assertEquals;
@@ -11,6 +20,7 @@
 import java.util.Map;
 
 import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.api.qualifier.haskind.ModelingKind;
 import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
 import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
 import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyType;
@@ -28,6 +38,7 @@
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.OperationVariable;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
 import org.junit.Before;
 import org.junit.Test;
 
@@ -54,9 +65,10 @@
 		elements1.add(getOperation());
 
 		elements2 = new ArrayList<ISubmodelElement>();
-		elements2.add(new Property("testId1"));
-		elements2.add(new Property("testId2"));
+		elements2.add(new Property("idShort1", "testId1"));
+		elements2.add(new Property("idShort2","testId2"));
 		elementCollection = new SubmodelElementCollection(elements2, false, false);
+		elementCollection.setIdShort("testCollectionId");
 	} 
 
 	@Test
@@ -64,15 +76,20 @@
 		SubmodelElementCollection elementCollection = new SubmodelElementCollection(elements1, true, true);
 		assertTrue(elementCollection.isAllowDuplicates());
 		assertTrue(elementCollection.isOrdered());
-		assertEquals(elements1, elementCollection.getValue());
+		
+		ISubmodelElement checkOperation = elementCollection.getSubmodelElements().get(OPERATION_ID);
+		assertEquals(OPERATION_ID, checkOperation.getIdShort());
 	} 
 	
 	@Test
 	public void testAddValue() {
-		ISubmodelElement element = new Property("testIdNew");
-		elementCollection.addElement(element);
+		Property element = new Property("testProperty");
+		element.setIdShort("propId");
+		elementCollection.addSubmodelElement(element);
 		elements2.add(element);
-		assertEquals(elements2, elementCollection.getValue());
+		
+		ISubmodelElement checkProperty = elementCollection.getSubmodelElements().get("propId");
+		assertEquals(element.getIdShort(), checkProperty.getIdShort());
 	} 
 	
 	@Test
@@ -85,9 +102,13 @@
 	@Test
 	public void testSetValue() {
 		Collection<ISubmodelElement> elements = new ArrayList<ISubmodelElement>();
-		elements.add(new Property("testId1"));
+		Property element = new Property("testProperty");
+		element.setIdShort("propId");
+		elements.add(element);
 		elementCollection.setValue(elements);
-		assertEquals(elements, elementCollection.getValue());
+		
+		ISubmodelElement checkProperty = elementCollection.getSubmodelElements().get("propId");
+		assertEquals(element.getIdShort(), checkProperty.getIdShort());
 	} 
 	
 	@Test
@@ -134,19 +155,47 @@
 	}
 
 	@Test
-	public void testAddSubModelElement() {
+	public void testAddSubmodelElement() {
 		SubmodelElementCollection collection = new SubmodelElementCollection(elements1, false, false);
+		String smCollIdShort = "coll1";
+		collection.setIdShort(smCollIdShort);
 		Property property = new Property("testValue");
 		String newIdShort = "newIdShort";
 		property.put(Referable.IDSHORT, newIdShort);
-		collection.addElement(property);
-		assertEquals(new Reference(new Key(KeyElements.SUBMODELELEMENTCOLLECTION, true, "", KeyType.IDSHORT)), property.getParent());
+		collection.addSubmodelElement(property);
+		assertEquals(new Reference(new Key(KeyElements.SUBMODELELEMENTCOLLECTION, true, smCollIdShort, KeyType.IDSHORT)), property.getParent());
 		Map<String, ISubmodelElement> submodelElements = new HashMap<String, ISubmodelElement>();
 		submodelElements.put(PROPERTY_ID, getProperty());
 		submodelElements.put(OPERATION_ID, getOperation());
 		submodelElements.put(newIdShort, property);
 		assertEquals(submodelElements, collection.getSubmodelElements());
 	}
+	
+	@Test
+	public void testGetSubmodelElement() {
+		SubmodelElementCollection collection = new SubmodelElementCollection(elements1, false, false);
+		ISubmodelElement retrievedElement = collection.getSubmodelElement(PROPERTY_ID);
+		assertEquals(getProperty(), retrievedElement);
+	}
+	
+	@Test(expected = ResourceNotFoundException.class)
+	public void testGetSubmodelElementNotExist() {
+		SubmodelElementCollection collection = new SubmodelElementCollection(elements1, false, false);
+		collection.getSubmodelElement("Id_Which_Does_Not_Exist");
+	}
+	
+	@Test(expected = ResourceNotFoundException.class)
+	public void testDeleteSubmodelElement() {
+		SubmodelElementCollection collection = new SubmodelElementCollection(elements1, false, false);
+		collection.deleteSubmodelElement(PROPERTY_ID);
+		collection.getSubmodelElement(PROPERTY_ID);
+	}
+	
+	@Test(expected = ResourceNotFoundException.class)
+	public void testDeleteSubmodelElementNotExist() {
+		SubmodelElementCollection collection = new SubmodelElementCollection(elements1, false, false);
+		collection.deleteSubmodelElement("Id_Which_Does_Not_Exist");
+	}
 
 	/**
 	 * Get a dummy property
@@ -168,8 +217,10 @@
 	 * @return operation
 	 */
 	private Operation getOperation() {
+		Property property = new Property("testOpVariableId");
+		property.setModelingKind(ModelingKind.TEMPLATE);
 		List<OperationVariable> variable = Collections
-				.singletonList(new OperationVariable(new Property("testOpVariableId")));
+				.singletonList(new OperationVariable(property));
 		Operation operation = new Operation(variable, variable, variable, null);
 		operation.put(Referable.IDSHORT, OPERATION_ID);
 		return operation;
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/TestSubmodelmodelElement.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/TestSubmodelmodelElement.java
deleted file mode 100644
index 226081f..0000000
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/TestSubmodelmodelElement.java
+++ /dev/null
@@ -1,103 +0,0 @@
-package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.submodelelement;
-
-import static org.junit.Assert.assertEquals;
-
-import java.util.Collection;
-import java.util.Collections;
-
-import org.eclipse.basyx.submodel.metamodel.api.dataspecification.IEmbeddedDataSpecification;
-import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
-import org.eclipse.basyx.submodel.metamodel.api.qualifier.haskind.ModelingKind;
-import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
-import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
-import org.eclipse.basyx.submodel.metamodel.map.dataspecification.EmbeddedDataSpecification;
-import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
-import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangStrings;
-import org.eclipse.basyx.submodel.metamodel.map.qualifier.qualifiable.Formula;
-import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
-import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElement;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * Tests constructor and getter of {@link SubmodelElement} for their
- * correctness
- * 
- * @author haque
- *
- */
-public class TestSubmodelmodelElement {
-	private static final Reference REFERENCE = new Reference(new Identifier(IdentifierType.CUSTOM, "testValue"), KeyElements.ACCESSPERMISSIONRULE, false);
-	private static final Formula FORMULA = new Formula(Collections.singleton(new Reference(new Key(KeyElements.BLOB, true, "TestValue", IdentifierType.IRI))));
-	
-	private SubmodelElement submodelElement;
-	
-	@Before
-	public void buidSubmodelElement() {
-		Property property = new Property("testId");
-		submodelElement = SubmodelElement.createAsFacade(property);
-	}
-	
-	@Test
-	public void testSetDataSpecificationReferences() {
-		Collection<IReference> refs = Collections.singleton(REFERENCE);
-		submodelElement.setDataSpecificationReferences(refs);
-		assertEquals(refs, submodelElement.getDataSpecificationReferences());
-	} 
-	
-	@Test
-	public void testSetEmbeddedDataSpecifications() {
-		EmbeddedDataSpecification embeddedDataSpecification = new EmbeddedDataSpecification();
-		Collection<IEmbeddedDataSpecification> specifications = Collections.singleton(embeddedDataSpecification);
-		submodelElement.setEmbeddedDataSpecifications(specifications);
-		assertEquals(specifications, submodelElement.getEmbeddedDataSpecifications());
-	}
-	
-	@Test
-	public void testSetIdShort() {
-		String newIdString = "newId";
-		submodelElement.setIdShort(newIdString);
-		assertEquals(newIdString, submodelElement.getIdShort());
-	}
-	
-	@Test
-	public void testSetCategory() {
-		String newCategoryString = "newCategory";
-		submodelElement.setCategory(newCategoryString);
-		assertEquals(newCategoryString, submodelElement.getCategory());
-	}
-	
-	@Test
-	public void testSetDescription() {
-		LangStrings newDescriptionString = new LangStrings("DE", "newTest");
-		submodelElement.setDescription(newDescriptionString);
-		assertEquals(newDescriptionString, submodelElement.getDescription());
-	}
-	
-	@Test
-	public void testSetParent() {
-		submodelElement.setParent(REFERENCE);
-		assertEquals(REFERENCE, submodelElement.getParent());
-	}
-	
-	@Test
-	public void testSetQualifier() {
-		submodelElement.setQualifier(Collections.singleton(FORMULA));
-		assertEquals(Collections.singleton(FORMULA), submodelElement.getQualifier());
-	}
-	
-	@Test
-	public void testSetSemanticID() {
-		submodelElement.setSemanticID(REFERENCE);
-		assertEquals(REFERENCE, submodelElement.getSemanticId());
-	}
-	
-	@Test
-	public void testSetModelingKind() {
-		ModelingKind newModelingKind = ModelingKind.TEMPLATE;
-		submodelElement.setModelingKind(newModelingKind);
-		assertEquals(newModelingKind, submodelElement.getModelingKind());
-	}
-}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/dataelement/TestBlob.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/dataelement/TestBlob.java
new file mode 100644
index 0000000..953d649
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/dataelement/TestBlob.java
@@ -0,0 +1,90 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.submodelelement.dataelement;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import java.nio.charset.StandardCharsets;
+import java.util.Base64;
+
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.Blob;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests if a Blob stores its data correctly
+ * 
+ * @author espen
+ *
+ */
+public class TestBlob {
+	public final String BLOB_CONTENT = "BLOB_VALUE";
+
+	protected Blob blob;
+	protected String testString = "NEW!";
+	protected byte[] testBytes = testString.getBytes(StandardCharsets.UTF_8);
+	protected String testBase64 = Base64.getEncoder().encodeToString(testBytes);
+	
+	@Before
+	public void build() {
+		blob = new Blob("testIdShort", "mimeType");
+	}
+	
+	/**
+	 * Tests if getMimeType() returns the correct value
+	 */
+	@Test
+	public void testGetMimeType() {
+		assertEquals("mimeType", blob.getMimeType());
+	}
+
+	/**
+	 * Tests if getValue() returns the correct value if it hasn't been set before
+	 */
+	@Test
+	public void testGetEmptyValue() {
+		assertNull(blob.getValue());
+	}
+
+	/**
+	 * Tests if setValue sets the correct values
+	 */
+	@Test
+	public void testSetValue() {
+		blob.setValue(testBase64);
+		assertEquals(testString, blob.getUTF8String());
+		assertArrayEquals(testBytes, blob.getByteArrayValue());
+		assertEquals(testBase64, blob.getValue());
+	}
+	
+	/**
+	 * Tests if setUTF8 sets the correct value
+	 */
+	@Test
+	public void testSetUTF8() {
+		blob.setUTF8String(testString);
+		assertEquals(testString, blob.getUTF8String());
+		assertArrayEquals(testBytes, blob.getByteArrayValue());
+		assertEquals(testBase64, blob.getValue());
+	}
+
+	/**
+	 * Tests if SetByteArrayValue() sets the correct value
+	 */
+	@Test
+	public void testSetByteArray() {
+		blob.setByteArrayValue(testBytes);
+		assertEquals(testString, blob.getUTF8String());
+		assertArrayEquals(testBytes, blob.getByteArrayValue());
+		assertEquals(testBase64, blob.getValue());
+	}
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/dataelement/TestFile.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/dataelement/TestFile.java
index b599c26..f5da076 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/dataelement/TestFile.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/dataelement/TestFile.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.submodelelement.dataelement;
 
 import static org.junit.Assert.assertEquals;
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/dataelement/TestReferenceElement.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/dataelement/TestReferenceElement.java
index 734685a..c5336c5 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/dataelement/TestReferenceElement.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/dataelement/TestReferenceElement.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.submodelelement.dataelement;
 
 import static org.junit.Assert.assertEquals;
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/dataelement/property/TestProperty.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/dataelement/property/TestProperty.java
index 565aaaa..97e3270 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/dataelement/property/TestProperty.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/dataelement/property/TestProperty.java
@@ -1,14 +1,29 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.submodelelement.dataelement.property;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.fail;
 
+import java.math.BigInteger;
+import java.time.Duration;
+import java.time.LocalDate;
+import java.time.Month;
+import java.time.Period;
 import java.util.Collections;
 
 import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
 import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
 import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
 import org.eclipse.basyx.submodel.metamodel.map.parts.ConceptDescription;
 import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangStrings;
 import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
@@ -17,10 +32,11 @@
 import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
 import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetypedef.PropertyValueTypeDef;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
 import org.junit.Before;
 import org.junit.Test;
 
+
 /**
  * Tests constructor, getter and setter of {@link Property} for their
  * correctness
@@ -30,7 +46,7 @@
  */
 public class TestProperty {
 	private static final String VALUE = "testValue";
-	private static final String STRING_TYPE = "string";
+	private static final ValueType STRING_TYPE = ValueType.String;
 	private Property property;
 
 	@Before
@@ -39,59 +55,69 @@
 	}
 	
 	@Test
-	public void testConstructor1() {
-		assertEquals(VALUE, property.get());
+	public void testConstructor1(){
+		assertEquals(VALUE, property.getValue());
 		assertNull(property.getValueId());
 		assertEquals(STRING_TYPE, property.getValueType());
 	} 
 	
 	@Test
-	public void testConstructor2() {
+	public void testConstructor2(){
 		Referable referable = new Referable("testIdShort", "testCategory", new LangStrings("DE", "test"));
 		Reference semanticId = new Reference(new Key(KeyElements.ASSET, true, "testValue", IdentifierType.IRI));
 		Qualifiable qualifiable = new Qualifiable(new Formula(Collections.singleton(new Reference(new Key(KeyElements.BLOB, true, "TestValue", IdentifierType.IRI)))));
 		Property property = new Property(VALUE, referable, semanticId, qualifiable);
-		assertEquals(VALUE, property.get());
+		assertEquals(VALUE, property.getValue());
 		assertNull(property.getValueId());
 		assertEquals(STRING_TYPE, property.getValueType());
 	} 
 	
 	@Test
 	public void testSetValueType() {
-		property.setValueType(PropertyValueTypeDef.String);
+		property.setValueType(ValueType.String);
 		assertEquals(STRING_TYPE, property.getValueType());
 	} 
 	
 	@Test
-	public void testGetNonMapValueType() {
-		property.put(Property.VALUETYPE, "string");
-		assertEquals("string", property.getValueType());
-	}
-	
-	@Test
-	public void testGetNotExistingValueType() {
-		// I would vote for fail fast - directly when setting the value
-		property.put(Property.VALUETYPE, "IDoNotExistInPropertyValueTypeDef");
-		try {
-			property.getValueType();
-			fail("Expecting exception when providing invalid type");
-		} catch (RuntimeException e) {
-		}
-	}
-	
-	@Test
-	public void testSet() {
+	public void testSet(){
+		Property booleanProp = new Property();
 		Boolean isSomething = true;
-		property.set(isSomething);
-		assertEquals(isSomething, property.get());
-		assertEquals("boolean", property.getValueType());
+		booleanProp.setValue(isSomething);
+		assertEquals(isSomething, booleanProp.getValue());
+		assertEquals(ValueType.Boolean, booleanProp.getValueType());
+
+		Byte byteNumber = new Byte("2");
+		Property byteProp = new Property();
+		byteProp.setValue(byteNumber);
+		assertEquals(byteNumber, byteProp.getValue());
+		assertEquals(ValueType.Int8, byteProp.getValueType());
+		
+		Duration duration = Duration.ofSeconds(10);
+		Property durationProp = new Property();
+		durationProp.setValue(duration);
+		assertEquals(duration, durationProp.getValue());
+		assertEquals(ValueType.Duration, durationProp.getValueType());
+
+		Property periodProp = new Property();
+		LocalDate today = LocalDate.now();
+		LocalDate birthday = LocalDate.of(1960, Month.JANUARY, 1);
+		Period p = Period.between(birthday, today);
+		periodProp.setValue(p);
+		assertEquals(p, periodProp.getValue());
+		assertEquals(ValueType.YearMonthDuration, periodProp.getValueType());
+
+		Property bigNumberProp = new Property();
+		BigInteger bignumber = new BigInteger("9223372036854775817");
+		bigNumberProp.setValue(bignumber);
+		assertEquals(bignumber, bigNumberProp.getValue());
+		assertEquals(ValueType.PositiveInteger, bigNumberProp.getValueType());
 	}
 
 	@Test
-	public void testSetCustom() {
-		property.set(null, PropertyValueTypeDef.String);
-		assertEquals(null, property.get());
-		assertEquals(PropertyValueTypeDef.String.getStandardizedLiteral(), property.getValueType());
+	public void testSetCustom(){
+		property.set(null, ValueType.String);
+		assertEquals(null, property.getValue());
+		assertEquals(ValueType.String, property.getValueType());
 	}
 
 	@Test
@@ -104,9 +130,32 @@
 
 	@Test
 	public void testAddConceptDescription() {
-		ConceptDescription description = new ConceptDescription();
+		String id = "idShort";
+		ConceptDescription description = new ConceptDescription(id, new Identifier(IdentifierType.IRDI, id));
 		Property property = new Property(VALUE);
 		property.addConceptDescription(description);
 		assertEquals(new Reference(description, KeyElements.CONCEPTDESCRIPTION, true), property.getSemanticId());
-	} 
+	}
+	
+	@Test
+	public void testInitializeWithNullValue() {
+		try {
+			// Should not work as valueType is a mandatory attribute
+			new Property("id", null);
+			fail();
+		} catch (RuntimeException e) {
+		}
+		
+		try {
+			// Should not work as valueType can not be set with null as value
+			Property prop = new Property();
+			prop.setValue(null);
+			fail();
+		} catch (RuntimeException e) {
+		}
+		
+		Property prop = new Property("id", "value");
+		// This should work as the valueType is already set
+		prop.setValue(null);
+	}
 }
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/dataelement/range/TestRange.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/dataelement/range/TestRange.java
new file mode 100644
index 0000000..d2a6c86
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/dataelement/range/TestRange.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.submodelelement.dataelement.range;
+
+import static org.junit.Assert.assertEquals;
+
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.range.Range;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.range.RangeValue;
+import org.junit.Before;
+import org.junit.Test;
+
+
+/**
+ * Test for Range
+ * 
+ * @author conradi
+ *
+ */
+public class TestRange {
+
+	private static final int MIN = 0;
+	private static final int MAX = 10;
+	private Range range;
+	
+	@Before
+	public void buildRange() {
+		range = new Range(ValueType.Integer, MIN, MAX);
+	}
+	
+	@Test
+	public void testGetValue() {
+		assertEquals(MIN, range.getMin());
+		assertEquals(MAX, range.getMax());
+		
+		RangeValue value = range.getValue();
+		assertEquals(MIN, value.getMin());
+		assertEquals(MAX, value.getMax());
+	} 
+	
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/operation/AsyncOperationHelper.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/operation/AsyncOperationHelper.java
new file mode 100644
index 0000000..284e0cf
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/operation/AsyncOperationHelper.java
@@ -0,0 +1,106 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.submodelelement.operation;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.function.Function;
+
+import org.eclipse.basyx.submodel.metamodel.api.qualifier.haskind.ModelingKind;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.OperationVariable;
+
+/**
+ * Helperclass for testing async invocations of Operations
+ * 
+ * @author conradi
+ *
+ */
+public class AsyncOperationHelper {
+	
+	public static final String ASYNC_OP_ID = "asyncOperation";
+	public static Collection<OperationVariable> IN;
+	protected static Collection<OperationVariable> OUT;
+	public static final String ASYNC_EXCEPTION_OP_ID = "asyncExceptionOperation";
+
+	private Object waitObject = new Object();
+	private boolean shouldWait = true;
+	
+	public AsyncOperationHelper() {
+		IN = new ArrayList<OperationVariable>();
+		OUT = new ArrayList<OperationVariable>();
+		Property asyncIn1 = new Property("asyncIn1", "");
+		asyncIn1.setModelingKind(ModelingKind.TEMPLATE);
+		Property asyncIn2 = new Property("asyncIn2", "");
+		asyncIn2.setModelingKind(ModelingKind.TEMPLATE);
+		IN.add(new OperationVariable(asyncIn1));
+		IN.add(new OperationVariable(asyncIn2));
+		Property asyncOut = new Property("asyncOut", "");
+		asyncOut.setModelingKind(ModelingKind.TEMPLATE);
+		OUT.add(new OperationVariable(asyncOut));
+	}
+	
+	private final Function<Object[], Object> ASYNC_FUNC = (Function<Object[], Object>) v -> {
+		int result = (int)v[0] + (int)v[1];
+		synchronized (waitObject) {
+			while (shouldWait) {
+				try {
+					waitObject.wait();
+				} catch (InterruptedException e) {
+				}
+			}
+		}
+		return result;
+	};
+	
+	private final Function<Object[], Object> ASYNC_EXCEPTION_FUNC = (Function<Object[], Object>) v -> {
+		NullPointerException ex = new NullPointerException();
+		synchronized (waitObject) {
+			while (shouldWait) {
+				try {
+					waitObject.wait();
+				} catch (InterruptedException e) {
+				}
+			}
+		}
+		throw ex;
+	};
+	
+	public Operation getAsyncOperation() {
+		shouldWait = true;
+		Operation op = new Operation(ASYNC_FUNC);
+		op.setIdShort(ASYNC_OP_ID);
+		op.setInputVariables(IN);
+		op.setOutputVariables(OUT);
+		return op;
+	}
+	
+	public Operation getAsyncExceptionOperation() {
+		shouldWait = true;
+		Operation op = new Operation(ASYNC_EXCEPTION_FUNC);
+		op.setIdShort(ASYNC_EXCEPTION_OP_ID);
+		return op;
+	}
+	
+	public void releaseWaitingOperation() {
+		shouldWait = false;
+		synchronized (waitObject) {
+			waitObject.notifyAll();
+		}
+		
+		// Give the Operation a bit of time to finish
+		try {
+			Thread.sleep(100);
+		} catch (InterruptedException e) {
+		}
+	}
+	
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/operation/TestOperation.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/operation/TestOperation.java
index f546717..de18ee7 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/operation/TestOperation.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/operation/TestOperation.java
@@ -1,6 +1,16 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.submodelelement.operation;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
 
 import java.util.ArrayList;
 import java.util.Collection;
@@ -10,108 +20,74 @@
 import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
 import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
 import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperation;
 import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
 import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.OperationVariable;
-import org.junit.Before;
 import org.junit.Test;
 
 /**
  * Tests constructor, getter and setter of {@link Operation} for their
  * correctness
  * 
- * @author haque
+ * @author haque, conradi
  *
  */
-public class TestOperation {
-	private static final Collection<OperationVariable> IN = Collections.singletonList(new OperationVariable(new Property("inValue")));
-	private static final Collection<OperationVariable> OUT = Collections.singletonList(new OperationVariable(new Property("outValue")));
-	private static final Collection<OperationVariable> INOUT = Collections.singletonList(new OperationVariable(new Property("inOutValue")));
-	private static final Function<Object[], Object> FUNC = (Function<Object[], Object>) v -> {
-		return (int)v[0] + (int)v[1];
-	};
+public class TestOperation extends TestOperationSuite {
 	
-	private Operation operation;
+	private static final String KEY_VALUE = "testKeyValue";
 	
-	@Before
-	public void buildOperation() {
-		operation = new Operation(FUNC);
+	@Override
+	protected IOperation prepareOperation(Operation operation) {
+		return operation;
 	}
 	
 	@Test
-	public void testConstructor1() throws Exception {
-		operation = new Operation(IN, OUT, INOUT, FUNC);
-		testInputVariables();
-		testOutputVariables();
-		testInOutputVariables();
-		testInvokable();
-	}
-	
-	@Test
-	public void testConstructor2() throws Exception {
-		assertEquals(new ArrayList<OperationVariable>(), operation.getInputVariables());
-		assertEquals(new ArrayList<OperationVariable>(), operation.getOutputVariables());
-		assertEquals(new ArrayList<OperationVariable>(), operation.getInOutputVariables());
-		testInvokable();
-	}
-
-	@Test
 	public void testOptionalElements() throws Exception {
 		operation = new Operation(null, null, null, FUNC);
 		assertEquals(0, operation.getInputVariables().size());
 		assertEquals(0, operation.getOutputVariables().size());
 		assertEquals(0, operation.getInOutputVariables().size());
-	} 
-	
-	@Test 
-	public void testSetInputVariables() {
-		operation.setInputVariables(IN);
-		testInputVariables();
-	}
-	
-	@Test 
-	public void testSetOutputVariables() {
-		operation.setOutputVariables(OUT);
-		testOutputVariables();
-	}
-	
-	@Test 
-	public void testSetInOutputVariables() {
-		operation.setInOutputVariables(INOUT);
-		testInOutputVariables();
 	}
 	
 	@Test 
 	public void testSetInvocable() throws Exception {
+		Operation operation = new Operation(IN, OUT, INOUT, FUNC);
+		assertEquals(5, operation.invoke(3, 2));
+		
 		Function<Object[], Object> newFunction = (Function<Object[], Object>) v -> {
 			return (int)v[0] - (int)v[1];
 		};
-		operation.setInvocable(newFunction);
+		operation.setInvokable(newFunction);
+		
 		assertEquals(1, operation.invoke(3,2));
 	}
-	
+
+	@Override
+	@Test
+	public void testInvokeWithSubmodelElements() {
+		Property param1 = new Property("testIn1", 1);
+		Property param2 = new Property("testIn2", 1);
+		try {
+			operation.invoke(param1, param2);
+			// Only unwrapped invokation is supported for local operations
+			fail();
+		} catch (UnsupportedOperationException e) {
+		}
+	}
+
 	@Test
 	public void testSetDataSpecificationReferences() {
-		Collection<IReference> references = Collections.singleton(new Reference(new Key(KeyElements.ASSET, true, "testValue", IdentifierType.IRI)));
+		Operation operation = new Operation(IN, OUT, INOUT, FUNC);
+		Collection<IReference> references = Collections.singleton(new Reference(new Key(KeyElements.ASSET, true, KEY_VALUE, IdentifierType.IRI)));
 		operation.setDataSpecificationReferences(references);
-		assertEquals(references, operation.getDataSpecificationReferences());
-	}
-	
-	private void testInvokable() throws Exception {
-		assertEquals(5, operation.invoke(2,3));
-	} 
-	
-	private void testInputVariables() {
-		assertEquals(IN, operation.getInputVariables());
-	}
-
-	private void testOutputVariables() {
-		assertEquals(OUT, operation.getOutputVariables());
-	}
-
-	private void testInOutputVariables() {
-		assertEquals(INOUT, operation.getInOutputVariables());
+		
+		Collection<IReference> newReferences = operation.getDataSpecificationReferences();
+		assertEquals(1, newReferences.size());
+		
+		IReference newReference = new ArrayList<>(newReferences).get(0);
+		
+		assertEquals(KEY_VALUE, newReference.getKeys().get(0).getValue());
 	}
 }
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/operation/TestOperationSuite.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/operation/TestOperationSuite.java
new file mode 100644
index 0000000..6eeb59d
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/operation/TestOperationSuite.java
@@ -0,0 +1,237 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.submodelelement.operation;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.function.Function;
+
+import org.eclipse.basyx.submodel.metamodel.api.qualifier.haskind.ModelingKind;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IAsyncInvocation;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperation;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperationVariable;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.OperationExecutionErrorException;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.OperationExecutionTimeoutException;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.OperationVariable;
+import org.eclipse.basyx.vab.exception.provider.WrongNumberOfParametersException;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests for IOperation
+ * 
+ * @author conradi
+ *
+ */
+public abstract class TestOperationSuite {
+	
+	protected static final String IN_VALUE = "inValue";
+	protected static final String OUT_VALUE = "outValue";
+	protected static final String INOUT_VALUE = "inOutValue";
+	protected static Collection<OperationVariable> IN;
+	protected static Collection<OperationVariable> OUT;
+	protected static Collection<OperationVariable> INOUT;
+	
+	protected static final Function<Object[], Object> FUNC = (Function<Object[], Object>) v -> {
+		return (int)v[0] + (int)v[1];
+	};
+	
+	protected static final Function<Object[], Object> EXCEPTION_FUNC = (Function<Object[], Object>) v -> {
+		throw new NullPointerException();
+	};
+	
+	protected IOperation operation;
+	protected IOperation operationException;
+
+	/**
+	 * Converts an Operation into the IOperation to be tested
+	 */
+	protected abstract IOperation prepareOperation(Operation operation);
+	
+	@Before
+	public void setup() {
+		IN = new ArrayList<OperationVariable>();
+		OUT = new ArrayList<OperationVariable>();
+		INOUT = new ArrayList<OperationVariable>();
+		Property inProp1 = new Property("testIn1", IN_VALUE);
+		inProp1.setModelingKind(ModelingKind.TEMPLATE);
+		Property inProp2 = new Property("testIn2", IN_VALUE);
+		inProp2.setModelingKind(ModelingKind.TEMPLATE);
+		Property outProp = new Property("testId2", OUT_VALUE);
+		outProp.setModelingKind(ModelingKind.TEMPLATE);
+		Property inOutProp = new Property("testId3", INOUT_VALUE);
+		inOutProp.setModelingKind(ModelingKind.TEMPLATE);
+		IN.add(new OperationVariable(inProp1));
+		IN.add(new OperationVariable(inProp2));
+		OUT.add(new OperationVariable(outProp));
+		INOUT.add(new OperationVariable(inOutProp));
+		
+		Operation op1 = new Operation(IN, OUT, INOUT, FUNC);
+		op1.setIdShort("op1");
+		operation = prepareOperation(op1);
+
+		Operation op2 = new Operation(IN, OUT, INOUT, EXCEPTION_FUNC);
+		op2.setIdShort("op2");
+		operationException = prepareOperation(op2);
+	}
+	
+	@Test
+	public void testInvoke() throws Exception {
+		assertEquals(5, operation.invoke(2, 3));
+	}
+	
+	@Test
+	public void testInvokeException() throws Exception {
+		try {
+			// Ensure the operation is invoked directly
+			operationException.invoke(1, 2);
+			fail();
+		} catch (Exception e) {
+			// Exceptions from ConnectedOperation are wrapped in ProviderException
+			assertTrue(e instanceof NullPointerException
+					|| e.getCause() instanceof NullPointerException);
+		}
+	}
+	
+	@Test
+	public void testInvokeWithSubmodelElements() {
+		Property param1 = new Property("testIn1", 2);
+		param1.setModelingKind(ModelingKind.TEMPLATE);
+		Property param2 = new Property("testIn2", 4);
+		param2.setModelingKind(ModelingKind.TEMPLATE);
+		SubmodelElement[] result = operation.invoke(param1, param2);
+		assertEquals(1, result.length);
+		assertEquals(6, result[0].getValue());
+	}
+
+	@Test
+	public void testInvokeParametersException() throws Exception {
+		try {
+			operation.invoke(1);
+			fail();
+		} catch (Exception e) {
+			// Exceptions from ConnectedOperation are wrapped in ProviderException
+			assertTrue(e instanceof WrongNumberOfParametersException
+					|| e.getCause() instanceof WrongNumberOfParametersException);
+		}
+	}
+
+	@Test
+	public void testInvokeAsync() throws Exception {
+		AsyncOperationHelper helper = new AsyncOperationHelper();
+		IOperation operation = prepareOperation(helper.getAsyncOperation());
+
+		IAsyncInvocation invocation = operation.invokeAsync(3, 2);
+		
+		assertFalse(invocation.isFinished());
+		
+		helper.releaseWaitingOperation();
+
+		assertTrue(invocation.isFinished());
+		assertEquals(5, invocation.getResult());
+	}
+	
+	@Test
+	public void testInvokeMultipleAsync() throws Exception {
+		AsyncOperationHelper helper = new AsyncOperationHelper();
+		IOperation operation = prepareOperation(helper.getAsyncOperation());
+
+		IAsyncInvocation invocation1 = operation.invokeAsync(1, 2);
+		IAsyncInvocation invocation2 = operation.invokeAsync(6, 2);
+
+		assertFalse(invocation1.isFinished());
+		assertFalse(invocation2.isFinished());
+
+		helper.releaseWaitingOperation();
+
+		assertTrue(invocation1.isFinished());
+		assertTrue(invocation2.isFinished());
+		assertEquals(3, invocation1.getResult());
+		assertEquals(8, invocation2.getResult());
+	}
+
+	@Test
+	public void testInvokeAsyncTimeout() throws Exception {
+		AsyncOperationHelper helper = new AsyncOperationHelper();
+		IOperation operation = prepareOperation(helper.getAsyncOperation());
+
+		// timeout of 1ms
+		IAsyncInvocation invocation = operation.invokeAsyncWithTimeout(1, 3, 2);
+
+		// Should be more than enough to trigger the timeout exception
+		Thread.sleep(100);
+		helper.releaseWaitingOperation();
+
+		assertTrue(invocation.isFinished());
+		try {
+			invocation.getResult();
+			fail();
+		} catch (OperationExecutionTimeoutException e) {
+		}
+	}
+
+	@Test
+	public void testInvokeExceptionAsync() throws Exception {
+		AsyncOperationHelper helper = new AsyncOperationHelper();
+		IOperation operationException = prepareOperation(helper.getAsyncExceptionOperation());
+		IAsyncInvocation invocation = operationException.invokeAsync();
+		assertFalse(invocation.isFinished());
+		
+		helper.releaseWaitingOperation();
+		
+		try {
+			invocation.getResult();
+			fail();
+		} catch (OperationExecutionErrorException e) {
+		}
+
+	}
+	
+	@Test
+	public void testInputVariables() {
+		Collection<IOperationVariable> inputVariables = operation.getInputVariables();
+		assertEquals(2, inputVariables.size());
+		Object value = getValueFromOpVariable(inputVariables);
+		assertEquals(IN_VALUE, value);
+	}
+
+	@Test
+	public void testOutputVariables() {
+		Collection<IOperationVariable> outputVariables = operation.getOutputVariables();
+		assertEquals(1, outputVariables.size());
+		Object value = getValueFromOpVariable(outputVariables);
+		assertEquals(OUT_VALUE, value);
+	}
+
+	@Test
+	public void testInOutputVariables() {
+		Collection<IOperationVariable> inoutVariables = operation.getInOutputVariables();
+		assertEquals(1, inoutVariables.size());
+		Object value = getValueFromOpVariable(inoutVariables);
+		assertEquals(INOUT_VALUE, value);
+	}
+	
+	/**
+	 * Gets the Value from the OperationVariable in a collection
+	 */
+	private Object getValueFromOpVariable(Collection<IOperationVariable> vars) {
+		IOperationVariable var = new ArrayList<>(vars).get(0);
+		return var.getValue().getValue();
+	}
+	
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/operation/TestOperationVariable.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/operation/TestOperationVariable.java
index 88b13d7..60f9ed7 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/operation/TestOperationVariable.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/operation/TestOperationVariable.java
@@ -1,8 +1,19 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.submodelelement.operation;
 
 import static org.junit.Assert.assertEquals;
 
+import org.eclipse.basyx.submodel.metamodel.api.qualifier.haskind.ModelingKind;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.OperationVariable;
 import org.junit.Before;
 import org.junit.Test;
@@ -15,11 +26,12 @@
  *
  */
 public class TestOperationVariable {
-	private static final Property PROPERTY = new Property("testOpVariable");
+	private static final Property PROPERTY = new Property("testIdShort", "testOpVariable");
 	
 	private OperationVariable operationVariable;
 	@Before
 	public void buildOperationVariable() {
+		PROPERTY.setModelingKind(ModelingKind.TEMPLATE);
 		operationVariable = new OperationVariable(PROPERTY);
 	} 
 	
@@ -30,8 +42,18 @@
 	
 	@Test
 	public void testSetValue() {
-		Property property = new Property("testNewProperty");
+		Property property = new Property("testIdShort", ValueType.String);
+		property.setModelingKind(ModelingKind.TEMPLATE);
 		operationVariable.setValue(property);
 		assertEquals(property, operationVariable.getValue());
 	}
+	
+	@Test
+	// TODO: Change with 1.0 Release when ModelingKind.Template is obligatory for OperationVariables
+	public void testSetValueChangedModelingKind() {
+		Property property = new Property("testIdShort", ValueType.String);
+		property.setModelingKind(ModelingKind.INSTANCE);
+		operationVariable.setValue(property);
+		assertEquals(ModelingKind.TEMPLATE, operationVariable.getValue().getModelingKind());
+	}
 }
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/relationship/TestAnnotatedRelationshipElement.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/relationship/TestAnnotatedRelationshipElement.java
new file mode 100644
index 0000000..79bf0a2
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/relationship/TestAnnotatedRelationshipElement.java
@@ -0,0 +1,88 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.submodelelement.relationship;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IDataElement;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.relationship.AnnotatedRelationshipElement;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.relationship.RelationshipElementValue;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests constructor, getter and setter of {@link AnnotatedRelationshipElement} for correctness
+ * 
+ * @author conradi
+ *
+ */
+public class TestAnnotatedRelationshipElement {
+	private static final Reference FIRST = new Reference(new Key(KeyElements.ASSET, true, "firstValue", IdentifierType.IRI));
+	private static final Reference SECOND = new Reference(new Identifier(IdentifierType.CUSTOM, "secondId"), KeyElements.BLOB, false);
+	
+	private AnnotatedRelationshipElement element;
+	
+	@Before
+	public void buildElement() {
+		element = new AnnotatedRelationshipElement("testId", FIRST, SECOND);
+		Property property = new Property("PropertyId", 10);
+		List<IDataElement> annotations = new ArrayList<>();
+		annotations.add(property);
+		element.setAnnotation(annotations);
+	} 
+	
+	@Test
+	public void testConstructor() {
+		assertEquals(FIRST, element.getFirst());
+		assertEquals(SECOND, element.getSecond());
+	} 
+	
+	@Test
+	public void testSetFirst() {
+		Reference newFirst = new Reference(new Key(KeyElements.CAPABILITY, false, "newFirst", IdentifierType.IRI));
+		element.setFirst(newFirst);
+		assertEquals(newFirst, element.getFirst());
+	} 
+
+	@Test
+	public void testSetSecond() {
+		Reference newSecond = new Reference(new Key(KeyElements.CAPABILITY, false, "newFirst", IdentifierType.IRI));
+		element.setSecond(newSecond);
+		assertEquals(newSecond, element.getSecond());
+	}
+	
+	@Test
+	public void testGetValue() {
+		RelationshipElementValue value = element.getValue();
+		assertEquals(FIRST.getKeys().get(0).getValue(), value.getFirst().getKeys().get(0).getValue());
+		assertEquals(SECOND.getKeys().get(0).getValue(), value.getSecond().getKeys().get(0).getValue());
+	}
+	
+	@Test
+	public void testGetAnnotations() {
+		Collection<IDataElement> annotations = element.getValue().getAnnotations();
+		assertEquals(1, annotations.size());
+		
+		// Check the element
+		for (IDataElement element: annotations) {
+			assertEquals("PropertyId", element.getIdShort());
+		}
+	}
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/relationship/TestRelationshipElement.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/relationship/TestRelationshipElement.java
index 0e63510..30cbcdf 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/relationship/TestRelationshipElement.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/relationship/TestRelationshipElement.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.submodelelement.relationship;
 
 import static org.junit.Assert.assertEquals;
@@ -8,6 +17,7 @@
 import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
 import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.relationship.RelationshipElement;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.relationship.RelationshipElementValue;
 import org.junit.Before;
 import org.junit.Test;
 
@@ -47,6 +57,13 @@
 		Reference newSecond = new Reference(new Key(KeyElements.CAPABILITY, false, "newFirst", IdentifierType.IRI));
 		relationshipElement.setSecond(newSecond);
 		assertEquals(newSecond, relationshipElement.getSecond());
-	} 
+	}
+	
+	@Test
+	public void testGetValue() {
+		RelationshipElementValue value = relationshipElement.getValue();
+		assertEquals(FIRST.getKeys().get(0).getValue(), value.getFirst().getKeys().get(0).getValue());
+		assertEquals(SECOND.getKeys().get(0).getValue(), value.getSecond().getKeys().get(0).getValue());
+	}
 	
 }
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/support/TestAASLambdaPropertyHelper.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/support/TestAASLambdaPropertyHelper.java
index ca8b1af..3f02b71 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/support/TestAASLambdaPropertyHelper.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/support/TestAASLambdaPropertyHelper.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.support;
 
 import static org.junit.Assert.assertEquals;
@@ -5,8 +14,8 @@
 import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.dataelement.ConnectedProperty;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.AASLambdaPropertyHelper;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetypedef.PropertyValueTypeDef;
-import org.eclipse.basyx.submodel.restapi.PropertyProvider;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
 import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
 import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaProvider;
 import org.junit.Test;
@@ -31,21 +40,21 @@
 		});
 		
 		// Wrap in provider
-		PropertyProvider provider = new PropertyProvider(new VABLambdaProvider(temperature));
+		SubmodelElementProvider provider = new SubmodelElementProvider(new VABLambdaProvider(temperature));
 		ConnectedProperty connectedProperty = new ConnectedProperty(new VABElementProxy("", provider));
 
 		// Check correct property type
-		String expectedType = PropertyValueTypeDef.Double.toString();
+		ValueType expectedType = ValueType.Double;
 		assertEquals(expectedType, connectedProperty.getValueType());
 		
 		// Check value is correctly retrievable by property
 		testValue = 10;
-		assertEquals(testValue, connectedProperty.get());
+		assertEquals(testValue, connectedProperty.getValue());
 		
 		// Check value is correctly written by property
 		double expectedValue = 2.1;
-		connectedProperty.set(expectedValue);
-		assertEquals(expectedValue, connectedProperty.get());
+		connectedProperty.setValue(expectedValue);
+		assertEquals(expectedValue, connectedProperty.getValue());
 		assertEquals(expectedValue, testValue, 0);
 	}
 }
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/restapi/SimpleAASSubmodel.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/restapi/SimpleAASSubmodel.java
index 672668d..9257cef 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/restapi/SimpleAASSubmodel.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/restapi/SimpleAASSubmodel.java
@@ -1,11 +1,26 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.submodel.restapi;
 
+import java.util.Arrays;
+import java.util.Collections;
 import java.util.function.Function;
 
-import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
+import org.eclipse.basyx.submodel.metamodel.api.qualifier.haskind.ModelingKind;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.OperationVariable;
 import org.eclipse.basyx.vab.exception.provider.ProviderException;
 
 /**
@@ -15,7 +30,11 @@
  * @author kuhn
  *
  */
-public class SimpleAASSubmodel extends SubModel {
+public class SimpleAASSubmodel extends Submodel {
+
+	public static final String INTPROPIDSHORT = "integerProperty";
+	public static final String OPERATIONSIMPLEIDSHORT = "simple";
+
 	public SimpleAASSubmodel() {
 		this("SimpleAASSubmodel");
 	}
@@ -27,31 +46,41 @@
 		// Create sub model
 
 		setIdShort(idShort);
+		setIdentification(new ModelUrn("simpleAASSubmodelUrn"));
 
 		Property intProp = new Property(123);
-		intProp.setIdShort("integerProperty");
-		addSubModelElement(intProp);
+		intProp.setIdShort(INTPROPIDSHORT);
+		addSubmodelElement(intProp);
 
 		Property stringProp = new Property("Test");
 		stringProp.setIdShort("stringProperty");
-		addSubModelElement(stringProp);
+		addSubmodelElement(stringProp);
 
-		Property nullProp = new Property(null);
-		nullProp.setIdShort("nullProperty");
-		addSubModelElement(nullProp);
+		Property nullProp = new Property("nullProperty", ValueType.String);
+		nullProp.setValue(null);
+		addSubmodelElement(nullProp);
 
 		// Create example operations
 		Operation complex = new Operation((Function<Object[], Object>) v -> {
 			return (int) v[0] - (int) v[1];
 		});
+		Property inProp1 = new Property("complexIn1", 0);
+		inProp1.setModelingKind(ModelingKind.TEMPLATE);
+		Property inProp2 = new Property("complexIn2", 0);
+		inProp2.setModelingKind(ModelingKind.TEMPLATE);
+		Property outProp = new Property("complexOut", 0);
+		outProp.setModelingKind(ModelingKind.TEMPLATE);
+		complex.setInputVariables(Arrays.asList(new OperationVariable(inProp1),
+				new OperationVariable(inProp2)));
+		complex.setOutputVariables(Collections.singleton(new OperationVariable(outProp)));
 		complex.setIdShort("complex");
-		addSubModelElement(complex);
+		addSubmodelElement(complex);
 
 		Operation simple = new Operation((Function<Object[], Object>) v -> {
 			return true;
 		});
-		simple.setIdShort("simple");
-		addSubModelElement(simple);
+		simple.setIdShort(OPERATIONSIMPLEIDSHORT);
+		addSubmodelElement(simple);
 
 		// Create example operations
 		// - Contained operation that throws native JAVA exception
@@ -59,22 +88,28 @@
 			throw new NullPointerException();
 		});
 		exception1.setIdShort("exception1");
-		addSubModelElement(exception1);
+		addSubmodelElement(exception1);
 
 		// - Contained operation that throws VAB exception
 		Operation exception2 = new Operation((Function<Object[], Object>) elId -> {
 			throw new ProviderException("Exception description");
 		});
 		exception2.setIdShort("exception2");
-		addSubModelElement(exception2);
+		addSubmodelElement(exception2);
 
+		Operation opInCollection = new Operation((Function<Object[], Object>) v -> {
+			return 123;
+		});
+		opInCollection.setIdShort("operationId");
+		
 		SubmodelElementCollection containerProp = new SubmodelElementCollection();
 		containerProp.setIdShort("container");
-		containerProp.addElement(intProp);
+		containerProp.addSubmodelElement(intProp);
+		containerProp.addSubmodelElement(opInCollection);
 
 		SubmodelElementCollection containerPropRoot = new SubmodelElementCollection();
 		containerPropRoot.setIdShort("containerRoot");
-		containerPropRoot.addElement(containerProp);
-		addSubModelElement(containerPropRoot);
+		containerPropRoot.addSubmodelElement(containerProp);
+		addSubmodelElement(containerPropRoot);
 	}
 }
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/restapi/SubModelProviderTest.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/restapi/SubModelProviderTest.java
deleted file mode 100644
index 3a6a7c4..0000000
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/restapi/SubModelProviderTest.java
+++ /dev/null
@@ -1,254 +0,0 @@
-package org.eclipse.basyx.testsuite.regression.submodel.restapi;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.eclipse.basyx.submodel.metamodel.map.qualifier.Identifiable;
-import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
-import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetypedef.PropertyValueTypeDefHelper;
-import org.eclipse.basyx.submodel.restapi.SubModelProvider;
-import org.eclipse.basyx.submodel.restapi.SubmodelElementProvider;
-import org.eclipse.basyx.testsuite.regression.vab.protocol.http.TestsuiteDirectory;
-import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
-import org.eclipse.basyx.vab.manager.VABConnectionManager;
-import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
-import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
-import org.eclipse.basyx.vab.protocol.api.ConnectorProvider;
-import org.junit.Test;
-
-public class SubModelProviderTest {
-	private VABConnectionManager connManager;
-	private static final String submodelAddr = "urn:fhg:es.iese:aas:1:1:submodel";
-
-	protected VABConnectionManager getConnectionManager() {
-		if (connManager == null) {
-			connManager = new VABConnectionManager(new TestsuiteDirectory(), new ConnectorProvider() {
-				@Override
-				protected IModelProvider createProvider(String addr) {
-					// Simple submodel for testing specific mappings for submodels
-					return new SubModelProvider(new SimpleAASSubmodel("mySubmodelId"));
-				}
-			});
-		}
-		return connManager;
-	}
-
-	/**
-	 * Tests accessing different paths that should be supported
-	 * @throws Exception 
-	 */
-	@Test
-	public void testPathsRaw() throws Exception {
-		SubModelProvider provider = new SubModelProvider(new SimpleAASSubmodel("mySubmodelId"));
-		provider.getModelPropertyValue("/submodel");
-		provider.getModelPropertyValue("/submodel/");
-
-		try {
-			provider.getModelPropertyValue("invalid");
-			fail();
-		} catch (Exception e) {
-			
-		}
-	}
-
-	/**
-	 * Test creating single property
-	 */
-	@SuppressWarnings("unchecked")
-	@Test
-	public void testCreateProperty() {
-		VABElementProxy submodelElement = getConnectionManager().connectToVABElement(submodelAddr);
-
-		// Create element
-		Property prop = new Property(500);
-		prop.setIdShort("newProperty");
-		submodelElement.createValue("/submodel/" + SubmodelElementProvider.PROPERTIES + "", prop);
-
-		// Read back value
-		Map<String, Object> result = (Map<String, Object>) submodelElement
-				.getModelPropertyValue("/submodel/" + SubmodelElementProvider.PROPERTIES + "/newProperty/value");
-		assertEquals(500, result.get(Property.VALUE));
-	}
-
-	/**
-	 * Test reading single property
-	 */
-	@SuppressWarnings("unchecked")
-	@Test
-	public void testReadProperty() {
-		VABElementProxy submodelElement = getConnectionManager().connectToVABElement(submodelAddr);
-
-		// Read list of properties
-		Object result = submodelElement.getModelPropertyValue("/submodel/" + SubmodelElementProvider.PROPERTIES + "");
-		Collection<Map<String, Object>> propertySet = (Collection<Map<String, Object>>) result;
-		Map<String, Object> property = propertySet.stream().filter(elem -> elem.get(Identifiable.IDSHORT).equals("integerProperty")).findFirst().get();
-		assertEquals(123, property.get(Property.VALUE));
-
-		// Read whole property
-		result = submodelElement.getModelPropertyValue("/submodel/" + SubmodelElementProvider.PROPERTIES + "/integerProperty");
-		property = (Map<String, Object>) result;
-		assertEquals(123, property.get(Property.VALUE));
-
-		// Read idShort
-		result = submodelElement.getModelPropertyValue("/submodel/" + SubmodelElementProvider.PROPERTIES + "/stringProperty");
-		property = (Map<String, Object>) result;
-		assertEquals("stringProperty", property.get(Identifiable.IDSHORT));
-
-		// Read single value
-		Map<String, Object> resMap = (Map<String, Object>) submodelElement
-				.getModelPropertyValue("/submodel/" + SubmodelElementProvider.PROPERTIES + "/stringProperty/value");
-		assertEquals("Test", resMap.get(Property.VALUE));
-
-		// Read null value
-		resMap = (Map<String, Object>) submodelElement
-				.getModelPropertyValue("/submodel/" + SubmodelElementProvider.PROPERTIES + "/nullProperty/value");
-		assertEquals(null, resMap.get(Property.VALUE));
-
-		// Read container property
-		Collection<Object> resSet = (Collection<Object>) submodelElement
-				.getModelPropertyValue("/submodel/submodelElements/containerRoot/value");
-		assertEquals(1, resSet.size());
-		resSet.forEach(x -> assertEquals("container", ((Map<String, Object>) x).get(Referable.IDSHORT)));
-
-		// Read nested property
-		String pathToNestedContainer = "/submodel/submodelElements/containerRoot/container";
-		String pathToNestedProperty = pathToNestedContainer + "/integerProperty/";
-		result = submodelElement.getModelPropertyValue(pathToNestedProperty);
-		property = (Map<String, Object>) result;
-		assertEquals(123, property.get(Property.VALUE));
-	}
-
-	/**
-	 * Test updating single property
-	 */
-	@SuppressWarnings("unchecked")
-	@Test
-	public void testUpdateProperty() {
-		VABElementProxy submodelElement = getConnectionManager().connectToVABElement(submodelAddr);
-
-		// Wrap object before updating element
-		Map<String, Object> updatedElement = new HashMap<>();
-		updatedElement.put(Property.VALUE, 3);
-		updatedElement.put("valueType", PropertyValueTypeDefHelper.getTypeWrapperFromObject(3));
-
-		// Update element
-		submodelElement.setModelPropertyValue("/submodel/" + SubmodelElementProvider.PROPERTIES + "/integerProperty/value", updatedElement);
-
-		// Check result
-		Map<String, Object> result = (Map<String, Object>) submodelElement
-				.getModelPropertyValue("/submodel/" + SubmodelElementProvider.PROPERTIES + "/integerProperty");
-		assertEquals(3, result.get(Property.VALUE));
-	}
-
-	/**
-	 * Test reading all properties of the submodel
-	 */
-	@SuppressWarnings("unchecked")
-	@Test
-	public void testReadProperties() {
-		VABElementProxy submodel = getConnectionManager().connectToVABElement(submodelAddr);
-		Collection<Map<String, Object>> set = (Collection<Map<String, Object>>) submodel.getModelPropertyValue("/submodel/" + SubmodelElementProvider.PROPERTIES);
-		// Should be two properties, one collection and four operations
-		assertEquals(3, set.size());
-	}
-
-	/**
-	 * Test reading all operations of the submodel
-	 */
-	@SuppressWarnings("unchecked")
-	@Test
-	public void testReadOperations() {
-		VABElementProxy submodel = getConnectionManager().connectToVABElement(submodelAddr);
-		Collection<Map<String, Object>> set = (Collection<Map<String, Object>>) submodel.getModelPropertyValue("/submodel/operations");
-		assertEquals(4, set.size());
-	}
-
-	/**
-	 * Test reading a single operation
-	 */
-	@SuppressWarnings("unchecked")
-	@Test
-	public void testReadSingleOperation() {
-		VABElementProxy submodel = getConnectionManager().connectToVABElement(submodelAddr);
-		Map<String, Object> operation = (Map<String, Object>) submodel.getModelPropertyValue("/submodel/operations/simple");
-		assertEquals("simple", operation.get(Identifiable.IDSHORT));
-	}
-
-	/**
-	 * Test reading all submodel elements of the submodel
-	 */
-	@SuppressWarnings("unchecked")
-	@Test
-	public void testReadSubModelElements() {
-		VABElementProxy submodel = getConnectionManager().connectToVABElement(submodelAddr);
-		Collection<Map<String, Object>> set = (Collection<Map<String, Object>>) submodel
-				.getModelPropertyValue("/submodel/submodelElements");
-		assertEquals(8, set.size());
-	}
-
-	/**
-	 * Test deleting a single property
-	 */
-	@Test
-	public void testDeleteProperty() {
-		VABElementProxy submodelElement = getConnectionManager().connectToVABElement(submodelAddr);
-
-		// Delete property
-		submodelElement.deleteValue("/submodel/" + SubmodelElementProvider.PROPERTIES + "/integerProperty");
-
-		// Test, if it has been deleted
-		try {
-			submodelElement.getModelPropertyValue("/submodel/" + SubmodelElementProvider.PROPERTIES + "/integerProperty");
-			fail();
-		} catch (ResourceNotFoundException e) {}
-	}
-
-	/**
-	 * Test deleting a single operation
-	 */
-	@Test
-	public void testDeleteOperation() {
-		VABElementProxy submodelElement = getConnectionManager().connectToVABElement(submodelAddr);
-
-		// Delete operation
-		submodelElement.deleteValue("/submodel/operations/simple");
-
-		// Test, if it has been deleted
-		try {
-			submodelElement.getModelPropertyValue("/submodel/operations/simple");
-			fail();
-		} catch (ResourceNotFoundException e) {}
-	}
-
-	/**
-	 * Test invoking an operation
-	 */
-	@Test
-	public void testInvokeOperation() {
-		VABElementProxy submodelElement = getConnectionManager().connectToVABElement(submodelAddr);
-
-		// Wrap parameters before invoking add-operation
-		Map<String, Object> param1 = new HashMap<>();
-		param1.put("idShort", "SecondNumber");
-		param1.put(Property.VALUE, 5);
-		param1.put("valueType", PropertyValueTypeDefHelper.getTypeWrapperFromObject(5));
-		Map<String, Object> param2 = new HashMap<>();
-		param2.put("idShort", "FirstNumber");
-		param2.put(Property.VALUE, 2);
-		param2.put("valueType", PropertyValueTypeDefHelper.getTypeWrapperFromObject(2));
-
-		// Invoke operation with wrapped parameters and check result
-		Object result = submodelElement.invokeOperation("/submodel/operations/complex", param1, param2);
-		assertEquals(3, result);
-
-		// Invoke operation on parent element
-		result = submodelElement.invokeOperation("/submodel/operations/simple");
-		assertTrue((boolean) result);
-	}
-}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/restapi/SubmodelProviderTest.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/restapi/SubmodelProviderTest.java
new file mode 100644
index 0000000..02406d0
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/restapi/SubmodelProviderTest.java
@@ -0,0 +1,571 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.submodel.restapi;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.facade.SubmodelElementMapCollectionConverter;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Identifiable;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueTypeHelper;
+import org.eclipse.basyx.submodel.restapi.MultiSubmodelElementProvider;
+import org.eclipse.basyx.submodel.restapi.OperationProvider;
+import org.eclipse.basyx.submodel.restapi.SubmodelProvider;
+import org.eclipse.basyx.submodel.restapi.operation.CallbackResponse;
+import org.eclipse.basyx.submodel.restapi.operation.ExecutionState;
+import org.eclipse.basyx.submodel.restapi.operation.InvocationResponse;
+import org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.submodelelement.operation.AsyncOperationHelper;
+import org.eclipse.basyx.testsuite.regression.vab.protocol.http.TestsuiteDirectory;
+import org.eclipse.basyx.vab.exception.provider.MalformedRequestException;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.eclipse.basyx.vab.manager.VABConnectionManager;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+import org.eclipse.basyx.vab.modelprovider.VABPathTools;
+import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
+import org.eclipse.basyx.vab.protocol.api.ConnectorFactory;
+import org.junit.Test;
+
+public class SubmodelProviderTest {
+	private VABConnectionManager connManager;
+	protected static final String submodelAddr = "urn:fhg:es.iese:aas:1:1:submodel";
+
+	protected VABConnectionManager getConnectionManager() {
+		if (connManager == null) {
+			connManager = new VABConnectionManager(new TestsuiteDirectory(), new ConnectorFactory() {
+				@Override
+				protected IModelProvider createProvider(String addr) {
+					// Simple submodel for testing specific mappings for submodels
+					return new SubmodelProvider(new SimpleAASSubmodel("mySubmodelId"));
+				}
+			});
+		}
+		return connManager;
+	}
+
+	/**
+	 * Tests accessing different paths that should be supported
+	 * @throws Exception 
+	 */
+	@Test
+	public void testPathsRaw() throws Exception {
+		SubmodelProvider provider = new SubmodelProvider(new SimpleAASSubmodel("mySubmodelId"));
+		provider.getValue("/submodel");
+		provider.getValue("/submodel/");
+
+		try {
+			provider.getValue("invalid");
+			fail();
+		} catch (Exception e) {
+			
+		}
+	}
+
+	/**
+	 * Test creating single property
+	 */
+	@Test
+	public void testCreateProperty() {
+		VABElementProxy submodelElement = getConnectionManager().connectToVABElement(submodelAddr);
+
+		// Create element
+		Property prop = new Property(500);
+		prop.setIdShort("newProperty");
+		submodelElement.setValue("/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/newProperty", prop);
+
+		// Read back value
+		Integer result = (Integer) submodelElement
+				.getValue("/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/newProperty/value");
+		assertEquals(500, result.intValue());
+	}
+
+	/**
+	 * Test updating a full property
+	 */
+	@Test
+	public void testUpdateFullProperty() {
+		VABElementProxy submodelElement = getConnectionManager().connectToVABElement(submodelAddr);
+
+		// Create element
+		Property prop = new Property("newProperty", 500);
+		submodelElement.setValue("/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/newProperty", prop);
+		
+		// Update element
+		Property updatedProp = new Property("newProperty", 400);
+		submodelElement.setValue("/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/newProperty", updatedProp);
+
+		// Read back value
+		Integer result = (Integer) submodelElement
+				.getValue("/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/newProperty/value");
+		assertEquals(400, result.intValue());
+	}
+
+	/**
+	 * Test creating single property
+	 */
+	@Test
+	public void testCreatePropertyInCollection() {
+		VABElementProxy submodelElement = getConnectionManager().connectToVABElement(submodelAddr);
+		
+		// Create element
+		Property prop = new Property(500);
+		prop.setIdShort("newProperty");
+		submodelElement.setValue("/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/containerRoot/newProperty", prop);
+		
+		// Read back value
+		Integer result = (Integer) submodelElement
+				.getValue("/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/containerRoot/newProperty/value");
+		assertEquals(500, result.intValue());
+
+
+		submodelElement.setValue("/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/containerRoot/container/newProperty", prop);
+
+		// Read back value
+		result = (Integer) submodelElement
+				.getValue("/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/containerRoot/container/newProperty/value");
+		assertEquals(500, result.intValue());
+	}
+
+	@Test
+	public void testUpdatePropertyInCollection() {
+		VABElementProxy submodelElement = getConnectionManager().connectToVABElement(submodelAddr);
+
+		// Create element
+		Property prop = new Property("newProperty", 500);
+		submodelElement.setValue(
+				"/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/containerRoot/container/newProperty", prop);
+
+		// Update element
+		Property prop2 = new Property("newProperty", 400);
+		submodelElement.setValue(
+				"/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/containerRoot/container/newProperty", prop2);
+
+		// Read back value
+		Integer result = (Integer) submodelElement.getValue(
+				"/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/containerRoot/container/newProperty/value");
+		assertEquals(400, result.intValue());
+	}
+
+	/**
+	 * Test reading single property
+	 */
+	@SuppressWarnings("unchecked")
+	@Test
+	public void testReadProperty() {
+		VABElementProxy submodelElement = getConnectionManager().connectToVABElement(submodelAddr);
+
+		// Read list of properties
+		Object result = submodelElement.getValue("/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "");
+		Collection<Map<String, Object>> propertySet = (Collection<Map<String, Object>>) result;
+		Map<String, Object> property = propertySet.stream().filter(elem -> elem.get(Identifiable.IDSHORT).equals("integerProperty")).findFirst().get();
+		assertEquals(123, property.get(Property.VALUE));
+
+		// Read whole property
+		result = submodelElement.getValue("/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/integerProperty");
+		property = (Map<String, Object>) result;
+		assertEquals(123, property.get(Property.VALUE));
+
+		// Read idShort
+		result = submodelElement.getValue("/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/stringProperty");
+		property = (Map<String, Object>) result;
+		assertEquals("stringProperty", property.get(Identifiable.IDSHORT));
+
+		// Read single value
+		String resString = (String) submodelElement
+				.getValue("/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/stringProperty/value");
+		assertEquals("Test", resString);
+
+		// Read null value
+		Object resObject = submodelElement
+				.getValue("/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/nullProperty/value");
+		assertEquals(null, resObject);
+
+		// Read container property
+		Collection<Object> resSet = (Collection<Object>) submodelElement
+				.getValue("/submodel/submodelElements/containerRoot/value");
+		assertEquals(1, resSet.size());
+		
+		// Get Collection from root-Collection
+		Map<String, Object> container = (Map<String, Object>) resSet.iterator().next();
+		
+		assertEquals("container", container.get(Referable.IDSHORT));
+		assertTrue(container.get(Property.VALUE) instanceof Collection<?>);
+		
+		// Get Value of nested Collection
+		Map<String, Object> containerValue = SubmodelElementMapCollectionConverter.convertCollectionToIDMap(container.get(Property.VALUE));
+		
+		// Check content of nested Collection
+		assertTrue(containerValue.containsKey("operationId"));
+		assertTrue(containerValue.containsKey("integerProperty"));
+		assertEquals(123, ((Property) containerValue.get("integerProperty")).getValue());
+
+		// Read nested property
+		String pathToNestedContainer = "/submodel/submodelElements/containerRoot/container";
+		String pathToNestedProperty = pathToNestedContainer + "/integerProperty/";
+		result = submodelElement.getValue(pathToNestedProperty);
+		property = (Map<String, Object>) result;
+		assertEquals(123, property.get(Property.VALUE));
+	}
+
+	/**
+	 * Test updating single property
+	 */
+	@SuppressWarnings("unchecked")
+	@Test
+	public void testUpdateProperty() {
+		VABElementProxy submodelElement = getConnectionManager().connectToVABElement(submodelAddr);
+
+		// Update element
+		submodelElement.setValue("/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/integerProperty/value", 3);
+
+		// Check result
+		Map<String, Object> result = (Map<String, Object>) submodelElement
+				.getValue("/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/integerProperty");
+		assertEquals(3, result.get(Property.VALUE));
+	}
+	
+	/**
+	 * Test updating a SubmodelElementCollection
+	 */
+	@SuppressWarnings("unchecked")
+	@Test
+	public void testUpdateSmElementCollection() {
+		VABElementProxy submodelElement = getConnectionManager().connectToVABElement(submodelAddr);
+		
+		Collection<ISubmodelElement> smElements = new ArrayList<>();
+		Property newProperty = new Property("propValue");
+		newProperty.setIdShort("propIdShort");
+		smElements.add(newProperty);
+		
+		// update value of smElemCollection
+		String path = VABPathTools.concatenatePaths("submodel", MultiSubmodelElementProvider.ELEMENTS, "containerRoot");
+		submodelElement.setValue(path + "/value", smElements);
+		
+		// read back the collection
+		Map<String, Object> map = (Map<String, Object>) submodelElement
+				.getValue(path);
+		
+		assertTrue(map.get(Property.VALUE) instanceof Collection<?>);
+		
+		Collection<Map<String, Object>> elements = (Collection<Map<String, Object>>) map.get(Property.VALUE);
+		assertEquals(1, elements.size());
+		
+		Iterator<Map<String, Object>> i = elements.iterator();
+		
+		assertEquals("propIdShort", i.next().get(Referable.IDSHORT));
+	}
+
+	/**
+	 * Test updating a Property inside a SubmodelElementCollection 
+	 */
+	@Test
+	public void testUpdateElementInSmElementCollection() {
+		VABElementProxy submodelElement = getConnectionManager().connectToVABElement(submodelAddr);
+
+		String path = VABPathTools.concatenatePaths("submodel", MultiSubmodelElementProvider.ELEMENTS,
+				"containerRoot", "container", "integerProperty", "value");
+
+		Integer value = (Integer) submodelElement.getValue(path);
+		assertEquals(123, value.intValue());
+
+		submodelElement.setValue(path, 321);
+
+		value = (Integer) submodelElement.getValue(path);
+		assertEquals(321, value.intValue());
+	}
+
+	/**
+	 * Test reading a single operation
+	 */
+	@SuppressWarnings("unchecked")
+	@Test
+	public void testReadSingleOperation() {
+		VABElementProxy submodel = getConnectionManager().connectToVABElement(submodelAddr);
+		Map<String, Object> operation = (Map<String, Object>) submodel.getValue("/submodel/submodelElements/simple");
+		assertEquals("simple", operation.get(Identifiable.IDSHORT));
+		
+		try {
+			submodel.getValue("/submodel/submodelElements/simple/value");
+			fail();
+		} catch (MalformedRequestException e) {
+			// An Operation has no value
+		}
+	}
+
+	/**
+	 * Checks if the submodel elements in a read submodel are within a collection
+	 */
+	@SuppressWarnings("unchecked")
+	@Test
+	public void testReadSubmodelCheckElementsInCollection() {
+		VABElementProxy submodel = getConnectionManager().connectToVABElement(submodelAddr);
+		Map<String, Object> smMap = (Map<String, Object>) submodel.getValue("/submodel");
+		Object o = smMap.get(Submodel.SUBMODELELEMENT);
+		assertTrue(o instanceof Collection<?>);
+	}
+
+	/**
+	 * Test reading all submodel elements of the submodel
+	 */
+	@SuppressWarnings("unchecked")
+	@Test
+	public void testReadSubmodelElements() {
+		VABElementProxy submodel = getConnectionManager().connectToVABElement(submodelAddr);
+		Collection<Map<String, Object>> set = (Collection<Map<String, Object>>) submodel
+				.getValue("/submodel/submodelElements");
+		assertEquals(8, set.size());
+	}
+
+	/**
+	 * Test deleting a single property
+	 */
+	@Test
+	public void testDeleteProperty() {
+		VABElementProxy submodelElement = getConnectionManager().connectToVABElement(submodelAddr);
+
+		// Delete property
+		submodelElement.deleteValue("/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/integerProperty");
+
+		// Test, if it has been deleted
+		try {
+			submodelElement.getValue("/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/integerProperty");
+			fail();
+		} catch (ResourceNotFoundException e) {}
+	}
+
+	/**
+	 * Test deleting a single operation
+	 */
+	@Test
+	public void testDeleteOperation() {
+		VABElementProxy submodelElement = getConnectionManager().connectToVABElement(submodelAddr);
+
+		// Delete operation
+		submodelElement.deleteValue("/submodel/submodelElements/simple");
+
+		// Test, if it has been deleted
+		try {
+			submodelElement.getValue("/submodel/submodelElements/simple");
+			fail();
+		} catch (ResourceNotFoundException e) {}
+	}
+	
+	/**
+	 * Test deleting a single property from a SubmodelElementCollection
+	 */
+	@Test
+	public void testDeletePropertyFromCollection() {
+		VABElementProxy submodelElement = getConnectionManager().connectToVABElement(submodelAddr);
+
+		String path = VABPathTools.concatenatePaths("submodel", MultiSubmodelElementProvider.ELEMENTS,
+				"containerRoot", "container", "integerProperty");
+		
+		assertNotNull(submodelElement.getValue(path));
+
+		// Delete property
+		submodelElement.deleteValue(path);
+		
+		// Test if parent Collection is still there
+		assertNotNull(submodelElement.getValue(VABPathTools.getParentPath(path)));
+
+		// Test, if it has been deleted
+		try {
+			submodelElement.getValue(path);
+			fail();
+		} catch (ResourceNotFoundException e) {}
+		
+		// Test delete the Collection "container"
+		path = VABPathTools.getParentPath(path);
+		
+		// Delete property
+		submodelElement.deleteValue(path);
+		
+		// Test if parent Collection is still there
+		assertNotNull(submodelElement.getValue(VABPathTools.getParentPath(path)));
+
+		// Test, if it has been deleted
+		try {
+			submodelElement.getValue(path);
+			fail();
+		} catch (ResourceNotFoundException e) {}
+	}
+
+	/**
+	 * Test invoking an operation
+	 */
+	@Test
+	public void testInvokeOperation() {
+		VABElementProxy submodelElement = getConnectionManager().connectToVABElement(submodelAddr);
+
+		// Wrap parameters before invoking add-operation
+		Map<String, Object> param1 = wrapParameter("FirstNumber", 5);
+		Map<String, Object> param2 = wrapParameter("SecondNumber", 2);
+
+		// Invoke operation with wrapped parameters and check result
+		Object result = submodelElement.invokeOperation("/submodel/submodelElements/complex/invoke", param1, param2);
+		assertEquals(3, result);
+
+		// Invoke operation on parent element
+		result = submodelElement.invokeOperation("/submodel/submodelElements/simple/invoke");
+		assertTrue((boolean) result);
+	}
+	
+	/**
+	 * Test invoking an operation from within a SubmodelElementCollection
+	 */
+	@Test
+	public void testInvokeOperationInCollection() {
+		VABElementProxy submodelElement = getConnectionManager().connectToVABElement(submodelAddr);
+		
+		String path = VABPathTools.concatenatePaths("submodel", MultiSubmodelElementProvider.ELEMENTS,
+				"containerRoot", "container", "operationId", "invoke");
+		
+		Object result = submodelElement.invokeOperation(path);
+		assertEquals(123, result);
+	}
+	
+	/**
+	 * Test getting /values of the Submodel
+	 */
+	@SuppressWarnings("unchecked")
+	@Test
+	public void testGetValues() {
+		VABElementProxy submodelElement = getConnectionManager().connectToVABElement(submodelAddr);
+		Map<String, Object> values = (Map<String, Object>) submodelElement.getValue("submodel/" + SubmodelProvider.VALUES);
+		
+		assertEquals(4, values.size());
+		
+		// Check if all expected Values are present
+		assertTrue(values.containsKey("containerRoot"));
+		Map<String, Object> collection1 = (Map<String, Object>) values.get("containerRoot");
+		
+		assertTrue(collection1.containsKey("container"));
+		Map<String, Object> collection2 = (Map<String, Object>) collection1.get("container");
+		
+		// Check the Value in /containerRoot/container/integerProperty
+		assertEquals(123, collection2.get("integerProperty"));
+		
+		assertEquals("Test", values.get("stringProperty"));
+		assertEquals(123, values.get("integerProperty"));
+		assertEquals(null, values.get("nullProperty"));
+	}
+	
+	@SuppressWarnings("unchecked")
+	@Test
+	public void testInvokeAsync() throws Exception {
+		VABElementProxy elementProxy = getConnectionManager().connectToVABElement(submodelAddr);
+		AsyncOperationHelper helper = new AsyncOperationHelper();
+		
+		String path = VABPathTools.concatenatePaths("submodel", MultiSubmodelElementProvider.ELEMENTS, AsyncOperationHelper.ASYNC_OP_ID);
+		elementProxy.setValue(path, helper.getAsyncOperation());
+		
+		// Wrap parameters before invoking add-operation
+		Map<String, Object> param1 = wrapParameter("FirstNumber", 5);
+		Map<String, Object> param2 = wrapParameter("SecondNumber", 2);
+		
+		path = VABPathTools.concatenatePaths("submodel", MultiSubmodelElementProvider.ELEMENTS, AsyncOperationHelper.ASYNC_OP_ID, "invoke?async=true");
+		
+		CallbackResponse response = CallbackResponse.createAsFacade((Map<String, Object>) elementProxy.invokeOperation(path, param1, param2));
+		String requestId = response.getRequestId();
+
+		String listPath = VABPathTools.concatenatePaths("submodel", MultiSubmodelElementProvider.ELEMENTS, AsyncOperationHelper.ASYNC_OP_ID, OperationProvider.INVOCATION_LIST);
+		
+		// Try correct operationId, wrong requestId
+		try {
+			elementProxy.getValue(VABPathTools.append(listPath, "nonexistent"));
+			fail();
+		} catch (ResourceNotFoundException e) {
+		}
+		
+		// Try wrong operationId, correct requestId
+		try {
+			elementProxy.getValue("/submodel/submodelElements/simple/invocationList/" + requestId);
+			fail();
+		} catch (ResourceNotFoundException e) {
+		}
+		
+		String requestPath = VABPathTools.append(listPath, requestId);
+		
+		// Check that it has not finished yet
+		InvocationResponse result = (InvocationResponse) elementProxy.getValue(requestPath);
+		assertEquals(ExecutionState.INITIATED, result.getExecutionState());
+		
+		helper.releaseWaitingOperation();
+		
+		result = (InvocationResponse) elementProxy.getValue(requestPath);
+		assertEquals(7, result.getFirstOutput());
+		
+		// Check if the async-invocation is deleted after retrieving its result
+		try {
+			elementProxy.getValue(requestPath);
+			fail();
+		} catch (ResourceNotFoundException e) {
+		}
+	}
+	
+	@SuppressWarnings("unchecked")
+	@Test
+	public void testInvokeAsyncException() throws Exception {
+		VABElementProxy submodelElement = getConnectionManager().connectToVABElement(submodelAddr);
+		AsyncOperationHelper helper = new AsyncOperationHelper();
+		
+		String path = VABPathTools.concatenatePaths("submodel", MultiSubmodelElementProvider.ELEMENTS, AsyncOperationHelper.ASYNC_EXCEPTION_OP_ID);
+		submodelElement.setValue(path, helper.getAsyncExceptionOperation());
+
+		path = VABPathTools.concatenatePaths("submodel", MultiSubmodelElementProvider.ELEMENTS,
+				AsyncOperationHelper.ASYNC_EXCEPTION_OP_ID, "invoke?async=true");
+		
+		CallbackResponse response = (CallbackResponse) submodelElement.invokeOperation(path);
+		String requestId = response.getRequestId();
+		
+		String requestPath = VABPathTools.concatenatePaths("submodel", MultiSubmodelElementProvider.ELEMENTS,
+				AsyncOperationHelper.ASYNC_EXCEPTION_OP_ID, OperationProvider.INVOCATION_LIST, requestId);
+		
+		// Check that it has not finished yet
+		InvocationResponse invResp = InvocationResponse
+				.createAsFacade((Map<String, Object>) submodelElement.getValue(requestPath));
+		assertNotEquals(ExecutionState.COMPLETED, invResp.getExecutionState());
+		assertNotEquals(ExecutionState.FAILED, invResp.getExecutionState());
+		
+		helper.releaseWaitingOperation();
+		
+
+		invResp = InvocationResponse
+				.createAsFacade((Map<String, Object>) submodelElement.getValue(requestPath));
+		assertEquals(ExecutionState.FAILED, invResp.getExecutionState());
+		
+		// Check if the async-invocation is deleted after retrieving its result
+		try {
+			submodelElement.getValue(requestPath);
+			fail();
+		} catch (ResourceNotFoundException e) {
+		}		
+	}
+	
+	private Map<String, Object> wrapParameter(String name, Object value) {
+		Map<String, Object> param = new HashMap<>();
+		param.put(Identifiable.IDSHORT, name);
+		param.put(Property.VALUE, value);
+		param.put(Property.VALUETYPE, ValueTypeHelper.getType(value).toString());
+		return param;
+	}
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/TestDigitalNameplateSubmodel.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/TestDigitalNameplateSubmodel.java
new file mode 100644
index 0000000..7045229
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/TestDigitalNameplateSubmodel.java
@@ -0,0 +1,171 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.submodel.types.digitalnameplate;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasSemantics;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Identifiable;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangString;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangStrings;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.MultiLanguageProperty;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.submodel.types.digitalnameplate.submodelelementcollections.address.Address;
+import org.eclipse.basyx.submodel.types.digitalnameplate.submodelelementcollections.assetspecificproperties.AssetSpecificProperties;
+import org.eclipse.basyx.submodel.types.digitalnameplate.submodelelementcollections.markings.Marking;
+import org.eclipse.basyx.submodel.types.digitalnameplate.submodelelementcollections.markings.Markings;
+import org.eclipse.basyx.submodel.types.digitalnameplate.DigitalNameplateSubmodel;
+import org.eclipse.basyx.testsuite.regression.submodel.types.digitalnameplate.submodelelementcollections.address.TestAddress;
+import org.eclipse.basyx.testsuite.regression.submodel.types.digitalnameplate.submodelelementcollections.assetspecificproperties.TestAssetSpecificProperties;
+import org.eclipse.basyx.testsuite.regression.submodel.types.digitalnameplate.submodelelementcollections.markings.TestMarking;
+import org.eclipse.basyx.testsuite.regression.submodel.types.digitalnameplate.submodelelementcollections.markings.TestMarkings;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests createAsFacade and isValid of {@link DigitalNameplateSubmodel} for their
+ * correctness
+ * 
+ * @author haque
+ *
+ */
+public class TestDigitalNameplateSubmodel {
+	public static MultiLanguageProperty manufacturerName = new MultiLanguageProperty(DigitalNameplateSubmodel.MANUFACTURERNAMEID);
+	public static MultiLanguageProperty designation = new MultiLanguageProperty(DigitalNameplateSubmodel.MANUFACTURERPRODUCTDESIGNATIONID);
+	public static Address address = new Address(TestAddress.street, TestAddress.zipCode, TestAddress.cityTown, TestAddress.nationalCode);
+	public static MultiLanguageProperty productFamily = new MultiLanguageProperty(DigitalNameplateSubmodel.MANUFACTURERPRODUCTFAMILYID);
+	public static Property serialNumber = new Property(DigitalNameplateSubmodel.SERIALNUMBERID, ValueType.String);
+	public static Property yearsOfConstruction = new Property(DigitalNameplateSubmodel.YEARSOFCONSTRUCTIONID, ValueType.String);
+	public static Markings markings;
+	public static AssetSpecificProperties assetSpecificProperties = new AssetSpecificProperties(Collections.singletonList(TestAssetSpecificProperties.guidelineSpecificProperties));
+	public static Identifier identifier = new Identifier(IdentifierType.IRI, "https://admin-shell.io/zvei/nameplate/1/0/Nameplate");
+	private Map<String, Object> submodelMap = new HashMap<String, Object>();
+	
+	@Before
+	public void buildFax() {
+		manufacturerName.setValue(new LangStrings(new LangString("DE", "Test Manufacturer")));
+		designation.setValue(new LangStrings(new LangString("DE", "Test Designation")));
+		productFamily.setValue(new LangStrings(new LangString("DE", "Test Product Family")));
+		serialNumber.setValue("123456");
+		yearsOfConstruction.setValue("2020");
+		
+		TestMarking.markingFile.setIdShort(Marking.MARKINGFILEID);
+		TestMarking.markingName.setValue("0173-1#07-DAA603#004");
+		TestMarkings.marking = new Marking(TestMarking.IDSHORT, TestMarking.markingName, TestMarking.markingFile);
+		TestMarkings.marking.setParent(new Reference(new Key(KeyElements.SUBMODELELEMENTCOLLECTION, true, Markings.IDSHORT, IdentifierType.IRDI)));
+		TestMarkings.markings = new ArrayList<Marking>();
+		TestMarkings.markings.add(TestMarkings.marking);
+		markings = new Markings(TestMarkings.markings);
+		
+		TestAddress.street.setValue(new LangStrings(new LangString("DE", "musterstraße 1")));
+		TestAddress.zipCode.setValue(new LangStrings(new LangString("DE", "12345")));
+		TestAddress.cityTown.setValue(new LangStrings(new LangString("DE", "MusterStadt")));
+		TestAddress.nationalCode.setValue(new LangStrings(new LangString("DE", "DE")));
+		
+		List<ISubmodelElement> elements = new ArrayList<ISubmodelElement>();
+		elements.add(manufacturerName);
+		elements.add(designation);
+		elements.add(productFamily);
+		elements.add(serialNumber);
+		elements.add(yearsOfConstruction);
+		elements.add(markings);
+		elements.add(address);
+		elements.add(assetSpecificProperties);
+		submodelMap.put(Referable.IDSHORT, DigitalNameplateSubmodel.SUBMODELID);
+		submodelMap.put(HasSemantics.SEMANTICID, DigitalNameplateSubmodel.SEMANTICID);
+		submodelMap.put(Submodel.SUBMODELELEMENT, elements);
+		submodelMap.put(Identifiable.IDENTIFICATION, identifier);
+	}
+
+	@Test
+	public void testCreateAsFacade() {
+		DigitalNameplateSubmodel submodelFromMap = DigitalNameplateSubmodel.createAsFacade(submodelMap);
+		assertEquals(DigitalNameplateSubmodel.SEMANTICID, submodelFromMap.getSemanticId());
+		assertEquals(manufacturerName, submodelFromMap.getManufacturerName());
+		assertEquals(designation, submodelFromMap.getManufacturerProductDesignation());
+		assertEquals(address, submodelFromMap.getAddress());
+		assertEquals(productFamily, submodelFromMap.getManufacturerProductFamily());
+		assertEquals(serialNumber, submodelFromMap.getSerialNumber());
+		assertEquals(yearsOfConstruction, submodelFromMap.getYearOfConstruction());
+		assertEquals(markings, submodelFromMap.getMarkings());
+		assertEquals(assetSpecificProperties, submodelFromMap.getAssetSpecificProperties());
+		assertEquals(DigitalNameplateSubmodel.SUBMODELID, submodelFromMap.getIdShort());
+		assertEquals(identifier, submodelFromMap.getIdentification());
+	}
+	
+	@Test (expected = MetamodelConstructionException.class)
+	public void testCreateAsFacadeExceptionIdShort() {
+		submodelMap.remove(Referable.IDSHORT);
+		DigitalNameplateSubmodel.createAsFacade(submodelMap);
+	}
+	
+	@Test (expected = MetamodelConstructionException.class)
+	public void testCreateAsFacadeExceptionIdentifier() {
+		submodelMap.remove(Identifiable.IDENTIFICATION);
+		DigitalNameplateSubmodel.createAsFacade(submodelMap);
+	}
+	
+	@SuppressWarnings("unchecked")
+	@Test (expected = ResourceNotFoundException.class)
+	public void testCreateAsFacadeExceptionManufacturerName() {
+		List<ISubmodelElement> elements = (List<ISubmodelElement>)submodelMap.get(Submodel.SUBMODELELEMENT);
+		elements.remove(manufacturerName);
+		DigitalNameplateSubmodel.createAsFacade(submodelMap);
+	}
+	
+	@SuppressWarnings("unchecked")
+	@Test (expected = ResourceNotFoundException.class)
+	public void testCreateAsFacadeExceptionZearsOfConstruction() {
+		List<ISubmodelElement> elements = (List<ISubmodelElement>)submodelMap.get(Submodel.SUBMODELELEMENT);
+		elements.remove(yearsOfConstruction);
+		DigitalNameplateSubmodel.createAsFacade(submodelMap);
+	}
+	
+	@SuppressWarnings("unchecked")
+	@Test (expected = ResourceNotFoundException.class)
+	public void testCreateAsFacadeExceptionManufacturerProductDesignation() {
+		List<ISubmodelElement> elements = (List<ISubmodelElement>)submodelMap.get(Submodel.SUBMODELELEMENT);
+		elements.remove(designation);
+		DigitalNameplateSubmodel.createAsFacade(submodelMap);
+	}
+	
+	@SuppressWarnings("unchecked")
+	@Test (expected = ResourceNotFoundException.class)
+	public void testCreateAsFacadeExceptionAddress() {
+		List<ISubmodelElement> elements = (List<ISubmodelElement>)submodelMap.get(Submodel.SUBMODELELEMENT);
+		elements.remove(address);
+		DigitalNameplateSubmodel.createAsFacade(submodelMap);
+	}
+	
+	@SuppressWarnings("unchecked")
+	@Test (expected = ResourceNotFoundException.class)
+	public void testCreateAsFacadeExceptionManufacturerProductFamily() {
+		List<ISubmodelElement> elements = (List<ISubmodelElement>)submodelMap.get(Submodel.SUBMODELELEMENT);
+		elements.remove(productFamily);
+		DigitalNameplateSubmodel.createAsFacade(submodelMap);
+	}
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/address/TestAddress.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/address/TestAddress.java
new file mode 100644
index 0000000..9da5fca
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/address/TestAddress.java
@@ -0,0 +1,171 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.submodel.types.digitalnameplate.submodelelementcollections.address;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasSemantics;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangString;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangStrings;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.MultiLanguageProperty;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.submodel.types.digitalnameplate.submodelelementcollections.address.Address;
+import org.eclipse.basyx.submodel.types.digitalnameplate.submodelelementcollections.address.Email;
+import org.eclipse.basyx.submodel.types.digitalnameplate.submodelelementcollections.address.Fax;
+import org.eclipse.basyx.submodel.types.digitalnameplate.submodelelementcollections.address.Phone;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests createAsFacade and isValid of {@link Address} for their
+ * correctness
+ * 
+ * @author haque
+ *
+ */
+public class TestAddress {
+	public static final String IDSHORT = "testAddressId";
+	public static MultiLanguageProperty department = new MultiLanguageProperty(Address.DEPARTMENTID);
+	public static MultiLanguageProperty street = new MultiLanguageProperty(Address.STREETID);
+	public static MultiLanguageProperty zipCode = new MultiLanguageProperty(Address.ZIPCODEID);
+	public static MultiLanguageProperty poBox = new MultiLanguageProperty(Address.POBOXID);
+	public static MultiLanguageProperty zipPoBox = new MultiLanguageProperty(Address.ZIPCODEOFPOBOXID);
+	public static MultiLanguageProperty cityTown = new MultiLanguageProperty(Address.CITYTOWNID);
+	public static MultiLanguageProperty stateCounty = new MultiLanguageProperty(Address.STATECOUNTYID);
+	public static MultiLanguageProperty nationalCode = new MultiLanguageProperty(Address.NATIONALCODEID);
+	public static MultiLanguageProperty vatNumber = new MultiLanguageProperty(Address.VATNUMBERID);
+	public static MultiLanguageProperty addressRemarks = new MultiLanguageProperty(Address.ADDRESSREMARKSID);
+	public static Property additLink = new Property(Address.ADDRESSOFADDITIONALLINKID, ValueType.String);
+	public static Phone phone1 = new Phone("Phone01", new LangString("DE", "123456789"));
+	public static Phone phone2 = new Phone("Phone02", new LangString("US", "123456711"));
+	public static Fax fax1 = new Fax("Fax01", new LangString("DE", "123456789"));
+	public static Fax fax2 = new Fax("Fax02", new LangString("DE", "123456711"));
+	public static Email email1 = new Email("Email01", new Property(Email.EMAILADDRESSID, "abc@test.com"));
+	public static Email email2 = new Email("Email02", new Property(Email.EMAILADDRESSID, "abcd@test.com"));
+	
+
+	private Map<String, Object> addressMap = new HashMap<String, Object>();
+	
+	@Before
+	public void buildFax() {
+		department.setValue(new LangStrings(new LangString("DE", "Dept Test")));
+		street.setValue(new LangStrings(new LangString("DE", "musterstraße 1")));
+		zipCode.setValue(new LangStrings(new LangString("DE", "12345")));
+		poBox.setValue(new LangStrings(new LangString("DE", "PE 1234")));
+		zipPoBox.setValue(new LangStrings(new LangString("DE", "12345")));
+		cityTown.setValue(new LangStrings(new LangString("DE", "MusterStadt")));
+		stateCounty.setValue(new LangStrings(new LangString("DE", "RLP")));
+		nationalCode.setValue(new LangStrings(new LangString("DE", "DE")));
+		vatNumber.setValue(new LangStrings(new LangString("DE", "123456")));
+		addressRemarks.setValue(new LangStrings(new LangString("DE", "test remarks")));
+		additLink.setValue("test.com");
+		
+		List<ISubmodelElement> elements = new ArrayList<ISubmodelElement>();
+		elements.add(department);
+		elements.add(street);
+		elements.add(zipCode);
+		elements.add(poBox);
+		elements.add(zipPoBox);
+		elements.add(cityTown);
+		elements.add(stateCounty);
+		elements.add(nationalCode);
+		elements.add(vatNumber);
+		elements.add(addressRemarks);
+		elements.add(additLink);
+		elements.add(phone1);
+		elements.add(phone2);
+		elements.add(fax1);
+		elements.add(fax2);
+		elements.add(email1);
+		elements.add(email2);
+		
+		addressMap.put(Referable.IDSHORT, IDSHORT);
+		addressMap.put(HasSemantics.SEMANTICID, Address.SEMANTICID);
+		addressMap.put(Property.VALUE, elements);
+	}
+	
+	@Test
+	public void testCreateAsFacade() {
+		Address addressFromMap = Address.createAsFacade(addressMap);
+		assertEquals(Address.SEMANTICID, addressFromMap.getSemanticId());
+		assertEquals(IDSHORT, addressFromMap.getIdShort());
+		assertEquals(department, addressFromMap.getDepartment());
+		assertEquals(street, addressFromMap.getStreet());
+		assertEquals(poBox, addressFromMap.getPOBox());
+		assertEquals(zipPoBox, addressFromMap.getZipCodeOfPOBox());
+		assertEquals(cityTown, addressFromMap.getCityTown());
+		assertEquals(stateCounty, addressFromMap.getStateCounty());
+		assertEquals(nationalCode, addressFromMap.getNationalCode());
+		assertEquals(zipCode, addressFromMap.getZipCode());
+		assertEquals(vatNumber, addressFromMap.getVatNumber());
+		assertEquals(addressRemarks, addressFromMap.getAddressRemarks());
+		assertEquals(additLink, addressFromMap.getAddressOfAdditionalLink());
+		List<Phone> phones = new ArrayList<Phone>();
+		phones.add(phone2);
+		phones.add(phone1);
+		List<Fax> faxes = new ArrayList<Fax>();
+		faxes.add(fax1);
+		faxes.add(fax2);
+		List<Email> emails = new ArrayList<Email>();
+		emails.add(email2);
+		emails.add(email1);
+		assertEquals(phones, addressFromMap.getPhone());
+		assertEquals(faxes, addressFromMap.getFax());
+		assertEquals(emails, addressFromMap.getEmail());
+	}
+	
+	@Test (expected = MetamodelConstructionException.class)
+	public void testCreateAsFacadeExceptionIdShort() {
+		addressMap.remove(Referable.IDSHORT);
+		Address.createAsFacade(addressMap);
+	}
+	
+	@SuppressWarnings("unchecked")
+	@Test (expected = ResourceNotFoundException.class)
+	public void testCreateAsFacadeExceptionStreet() {
+		List<ISubmodelElement> elements = (List<ISubmodelElement>)addressMap.get(Property.VALUE);
+		elements.remove(street);
+		Address.createAsFacade(addressMap);
+	}
+	
+	@SuppressWarnings("unchecked")
+	@Test (expected = ResourceNotFoundException.class)
+	public void testCreateAsFacadeExceptionZipCode() {
+		List<ISubmodelElement> elements = (List<ISubmodelElement>)addressMap.get(Property.VALUE);
+		elements.remove(zipCode);
+		Address.createAsFacade(addressMap);
+	}
+	
+	@SuppressWarnings("unchecked")
+	@Test (expected = ResourceNotFoundException.class)
+	public void testCreateAsFacadeExceptionCityTown() {
+		List<ISubmodelElement> elements = (List<ISubmodelElement>)addressMap.get(Property.VALUE);
+		elements.remove(cityTown);
+		Address.createAsFacade(addressMap);
+	}
+	
+	@SuppressWarnings("unchecked")
+	@Test (expected = ResourceNotFoundException.class)
+	public void testCreateAsFacadeExceptionNationalCode() {
+		List<ISubmodelElement> elements = (List<ISubmodelElement>)addressMap.get(Property.VALUE);
+		elements.remove(nationalCode);
+		Address.createAsFacade(addressMap);
+	}
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/address/TestEmail.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/address/TestEmail.java
new file mode 100644
index 0000000..7397b47
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/address/TestEmail.java
@@ -0,0 +1,90 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.submodel.types.digitalnameplate.submodelelementcollections.address;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasSemantics;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangString;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangStrings;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.MultiLanguageProperty;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.submodel.types.digitalnameplate.enums.MailType;
+import org.eclipse.basyx.submodel.types.digitalnameplate.submodelelementcollections.address.Email;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests createAsFacade and isValid of {@link Email} for their
+ * correctness
+ * 
+ * @author haque
+ *
+ */
+public class TestEmail {
+	public static final String IDSHORT = "testEmailId";
+	public static Property emailAddress = new Property(Email.EMAILADDRESSID, ValueType.String);
+	public static MultiLanguageProperty publicKey = new MultiLanguageProperty(Email.PUBLICKEYID);
+	public static Property typeOfEmailAddress = new Property(Email.TYPEOFEMAILADDRESSID, ValueType.String);
+	public static MultiLanguageProperty typeOfPublicKey = new MultiLanguageProperty(Email.TYPEOFPUBLICKEYID);
+
+	private Map<String, Object> emailMap = new HashMap<String, Object>();
+	
+	@Before
+	public void buildFax() {
+		emailAddress.setValue("test@muster-ag.de");
+		publicKey.setValue(new LangStrings(new LangString("DE", "123456")));
+		typeOfEmailAddress.setValue(MailType.SECRETARY);
+		typeOfPublicKey.setValue(new LangStrings(new LangString("DE", "1234")));
+		List<ISubmodelElement> elements = new ArrayList<ISubmodelElement>();
+		elements.add(emailAddress);
+		elements.add(publicKey);
+		elements.add(typeOfEmailAddress);
+		elements.add(typeOfPublicKey);
+		emailMap.put(Referable.IDSHORT, IDSHORT);
+		emailMap.put(HasSemantics.SEMANTICID, Email.SEMANTICID);
+		emailMap.put(Property.VALUE, elements);
+	}
+	
+	@Test
+	public void testCreateAsFacade() {
+		Email emailFromMap = Email.createAsFacade(emailMap);
+		assertEquals(Email.SEMANTICID, emailFromMap.getSemanticId());
+		assertEquals(emailAddress, emailFromMap.getEmailAddress());
+		assertEquals(publicKey, emailFromMap.getPublicKey());
+		assertEquals(typeOfEmailAddress, emailFromMap.getTypeOfEmailAddress());
+		assertEquals(typeOfPublicKey, emailFromMap.getTypeOfPublicKey());
+		assertEquals(IDSHORT, emailFromMap.getIdShort());
+	}
+	
+	@Test (expected = MetamodelConstructionException.class)
+	public void testCreateAsFacadeExceptionIdShort() {
+		emailMap.remove(Referable.IDSHORT);
+		Email.createAsFacade(emailMap);
+	}
+	
+	@Test (expected = ResourceNotFoundException.class)
+	public void testCreateAsFacadeExceptionEmailAddress() {
+		List<ISubmodelElement> newElements = new ArrayList<ISubmodelElement>();
+		newElements.add(typeOfEmailAddress);
+		emailMap.put(Property.VALUE, newElements);
+		Email.createAsFacade(emailMap);
+	}
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/address/TestFax.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/address/TestFax.java
new file mode 100644
index 0000000..40f7069
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/address/TestFax.java
@@ -0,0 +1,82 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.submodel.types.digitalnameplate.submodelelementcollections.address;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasSemantics;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangString;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangStrings;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.MultiLanguageProperty;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.submodel.types.digitalnameplate.enums.FaxType;
+import org.eclipse.basyx.submodel.types.digitalnameplate.submodelelementcollections.address.Fax;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests createAsFacade and isValid of {@link Fax} for their
+ * correctness
+ * 
+ * @author haque
+ *
+ */
+public class TestFax {
+	public static final String IDSHORT = "testFaxId";
+	public static MultiLanguageProperty faxNumber = new MultiLanguageProperty(Fax.FAXNUMBERID);
+	public static Property typeOfFax = new Property(Fax.TYPEOFFAXID, ValueType.String);
+
+	private Map<String, Object> faxMap = new HashMap<String, Object>();
+	
+	@Before
+	public void buildFax() {
+		faxNumber.setValue(new LangStrings(new LangString("DE", "0631123456")));
+		typeOfFax.setValue(FaxType.HOME);
+		List<ISubmodelElement> elements = new ArrayList<ISubmodelElement>();
+		elements.add(faxNumber);
+		elements.add(typeOfFax);
+		faxMap.put(Referable.IDSHORT, IDSHORT);
+		faxMap.put(HasSemantics.SEMANTICID, Fax.SEMANTICID);
+		faxMap.put(Property.VALUE, elements);
+	}
+
+	@Test
+	public void testCreateAsFacade() {
+		Fax faxFromMap = Fax.createAsFacade(faxMap);
+		assertEquals(Fax.SEMANTICID, faxFromMap.getSemanticId());
+		assertEquals(faxNumber, faxFromMap.getFaxNumber());
+		assertEquals(typeOfFax, faxFromMap.getTypeOfFaxNumber());
+		assertEquals(IDSHORT, faxFromMap.getIdShort());
+	}
+	
+	@Test (expected = MetamodelConstructionException.class)
+	public void testCreateAsFacadeExceptionIdShort() {
+		faxMap.remove(Referable.IDSHORT);
+		Fax.createAsFacade(faxMap);
+	}
+	
+	@Test (expected = ResourceNotFoundException.class)
+	public void testCreateAsFacadeExceptionFaxNumber() {
+		List<ISubmodelElement> newElements = new ArrayList<ISubmodelElement>();
+		newElements.add(typeOfFax);
+		faxMap.put(Property.VALUE, newElements);
+		Fax.createAsFacade(faxMap);
+	}
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/address/TestPhone.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/address/TestPhone.java
new file mode 100644
index 0000000..575daa4
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/address/TestPhone.java
@@ -0,0 +1,81 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.submodel.types.digitalnameplate.submodelelementcollections.address;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasSemantics;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangString;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangStrings;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.MultiLanguageProperty;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.submodel.types.digitalnameplate.enums.PhoneType;
+import org.eclipse.basyx.submodel.types.digitalnameplate.submodelelementcollections.address.Phone;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests createAsFacade and isValid of {@link Phone} for their
+ * correctness
+ * 
+ * @author haque
+ *
+ */
+public class TestPhone {
+	public static final String IDSHORT = "testPhoneId";
+	public static MultiLanguageProperty telephone = new MultiLanguageProperty(Phone.TELEPHONENUMBERID);
+	public static Property typeOfTelephone = new Property(Phone.TYPEOFTELEPHONEID, ValueType.String);
+	private Map<String, Object> phoneMap = new HashMap<String, Object>();
+	
+	@Before
+	public void buildPhone() {
+		telephone.setValue(new LangStrings(new LangString("DE", "0631123456")));
+		typeOfTelephone.setValue(PhoneType.HOME);
+		List<ISubmodelElement> elements = new ArrayList<ISubmodelElement>();
+		elements.add(telephone);
+		elements.add(typeOfTelephone);
+		phoneMap.put(Referable.IDSHORT, IDSHORT);
+		phoneMap.put(HasSemantics.SEMANTICID, Phone.SEMANTICID);
+		phoneMap.put(Property.VALUE, elements);
+	}
+	
+	@Test
+	public void testCreateAsFacade() {
+		Phone phoneFromMap = Phone.createAsFacade(phoneMap);
+		assertEquals(Phone.SEMANTICID, phoneFromMap.getSemanticId());
+		assertEquals(telephone, phoneFromMap.getTelephoneNumber());
+		assertEquals(typeOfTelephone, phoneFromMap.getTypeOfTelephone());
+		assertEquals(IDSHORT, phoneFromMap.getIdShort());
+	}
+	
+	@Test (expected = MetamodelConstructionException.class)
+	public void testCreateAsFacadeExceptionIdShort() {
+		phoneMap.remove(Referable.IDSHORT);
+		Phone.createAsFacade(phoneMap);
+	}
+	
+	@Test (expected = ResourceNotFoundException.class)
+	public void testCreateAsFacadeExceptionTelephoneNumber() {
+		List<ISubmodelElement> newElements = new ArrayList<ISubmodelElement>();
+		newElements.add(typeOfTelephone);
+		phoneMap.put(Property.VALUE, newElements);
+		Phone.createAsFacade(phoneMap);
+	}
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/assetspecificproperties/TestAssetSpecificProperties.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/assetspecificproperties/TestAssetSpecificProperties.java
new file mode 100644
index 0000000..eba7643
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/assetspecificproperties/TestAssetSpecificProperties.java
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.submodel.types.digitalnameplate.submodelelementcollections.assetspecificproperties;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasSemantics;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.types.digitalnameplate.submodelelementcollections.assetspecificproperties.AssetSpecificProperties;
+import org.eclipse.basyx.submodel.types.digitalnameplate.submodelelementcollections.assetspecificproperties.GuidelineSpecificProperties;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests createAsFacade and isValid of {@link AssetSpecificProperties} for their
+ * correctness
+ * 
+ * @author haque
+ *
+ */
+public class TestAssetSpecificProperties {
+	public static final String IDSHORT = "AssetSpecificProperties";
+	public static GuidelineSpecificProperties guidelineSpecificProperties = new GuidelineSpecificProperties(TestGuidelineSpecificProperties.IDSHORT, TestGuidelineSpecificProperties.conformityDeclaration, Collections.singletonList(TestGuidelineSpecificProperties.arbitrary));
+	
+	private Map<String, Object> assetMap = new HashMap<String, Object>();
+	
+	@Before
+	public void buildAssetSpecificProperties() {
+		
+		List<ISubmodelElement> elements = new ArrayList<ISubmodelElement>();
+		elements.add(guidelineSpecificProperties);
+		
+		assetMap.put(Referable.IDSHORT, IDSHORT);
+		assetMap.put(HasSemantics.SEMANTICID, AssetSpecificProperties.SEMANTICID);
+		assetMap.put(Property.VALUE, elements);
+	}
+	
+	@Test
+	public void testCreateAsFacade() {
+		AssetSpecificProperties assetFromMap = AssetSpecificProperties.createAsFacade(assetMap);
+		assertEquals(AssetSpecificProperties.SEMANTICID, assetFromMap.getSemanticId());
+		assertEquals(Collections.singletonList(guidelineSpecificProperties), assetFromMap.getGuidelineSpecificProperties());
+		assertEquals(IDSHORT, assetFromMap.getIdShort());
+	}
+	
+	@Test (expected = MetamodelConstructionException.class)
+	public void testCreateAsFacadeExceptionIdShort() {
+		assetMap.remove(Referable.IDSHORT);
+		AssetSpecificProperties.createAsFacade(assetMap);
+	}
+	
+	@SuppressWarnings("unchecked")
+	@Test (expected = MetamodelConstructionException.class)
+	public void testCreateAsFacadeExceptionGuideline() {
+		List<ISubmodelElement> elements = (List<ISubmodelElement>)assetMap.get(Property.VALUE);
+		elements.remove(guidelineSpecificProperties);
+		AssetSpecificProperties.createAsFacade(assetMap);
+	}
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/assetspecificproperties/TestGuidelineSpecificProperties.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/assetspecificproperties/TestGuidelineSpecificProperties.java
new file mode 100644
index 0000000..c23dfa0
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/assetspecificproperties/TestGuidelineSpecificProperties.java
@@ -0,0 +1,89 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.submodel.types.digitalnameplate.submodelelementcollections.assetspecificproperties;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasSemantics;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.submodel.types.digitalnameplate.submodelelementcollections.assetspecificproperties.GuidelineSpecificProperties;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests createAsFacade and isValid of {@link GuidelineSpecificProperties} for their
+ * correctness
+ * 
+ * @author haque
+ *
+ */
+public class TestGuidelineSpecificProperties {
+	public static final String IDSHORT = "GuidelineSpecificProperties01";
+	public static Property conformityDeclaration = new Property(GuidelineSpecificProperties.GUIDELINEFORCONFORMITYDECLARATIONID, ValueType.String);
+	public static Property arbitrary = new Property("arbitraryId", ValueType.String);
+	
+	private Map<String, Object> guidelineMap = new HashMap<String, Object>();
+	
+	@Before
+	public void buildGuidelineSpecificProperties() {
+		conformityDeclaration.setValue("test Declaration");
+		arbitrary.setValue("0173-1#07-DAA603#004");
+		
+		List<ISubmodelElement> elements = new ArrayList<ISubmodelElement>();
+		elements.add(conformityDeclaration);
+		elements.add(arbitrary);
+		
+		guidelineMap.put(Referable.IDSHORT, IDSHORT);
+		guidelineMap.put(HasSemantics.SEMANTICID, GuidelineSpecificProperties.SEMANTICID);
+		guidelineMap.put(Property.VALUE, elements);
+	}
+	
+	@Test
+	public void testCreateAsFacade() {
+		GuidelineSpecificProperties guidelineFromMap = GuidelineSpecificProperties.createAsFacade(guidelineMap);
+		assertEquals(GuidelineSpecificProperties.SEMANTICID, guidelineFromMap.getSemanticId());
+		assertEquals(conformityDeclaration, guidelineFromMap.getGuidelineForConformityDeclaration());
+		assertEquals(Collections.singletonList(arbitrary), guidelineFromMap.getArbitrary());
+		assertEquals(IDSHORT, guidelineFromMap.getIdShort());
+	}
+	
+	@Test (expected = MetamodelConstructionException.class)
+	public void testCreateAsFacadeExceptionIdShort() {
+		guidelineMap.remove(Referable.IDSHORT);
+		GuidelineSpecificProperties.createAsFacade(guidelineMap);
+	}
+	
+	@SuppressWarnings("unchecked")
+	@Test (expected = MetamodelConstructionException.class)
+	public void testCreateAsFacadeExceptionArbitrary() {
+		List<ISubmodelElement> elements = (List<ISubmodelElement>)guidelineMap.get(Property.VALUE);
+		elements.remove(arbitrary);
+		GuidelineSpecificProperties.createAsFacade(guidelineMap);
+	}
+
+	@SuppressWarnings("unchecked")
+	@Test (expected = ResourceNotFoundException.class)
+	public void testCreateAsFacadeExceptionDeclaration() {
+		List<ISubmodelElement> elements = (List<ISubmodelElement>)guidelineMap.get(Property.VALUE);
+		elements.remove(conformityDeclaration);
+		GuidelineSpecificProperties.createAsFacade(guidelineMap);
+	}
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/markings/TestMarking.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/markings/TestMarking.java
new file mode 100644
index 0000000..c3939be
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/markings/TestMarking.java
@@ -0,0 +1,94 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.submodel.types.digitalnameplate.submodelelementcollections.markings;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasSemantics;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.File;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.submodel.types.digitalnameplate.submodelelementcollections.markings.Marking;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests createAsFacade and isValid of {@link Marking} for their
+ * correctness
+ * 
+ * @author haque
+ *
+ */
+public class TestMarking {
+	public static final String IDSHORT = "Marking01";
+	public static Property markingName = new Property(Marking.MARKINGNAMEID, ValueType.String);
+	public static File markingFile = new File("/to/the/image.jpg", "image/jpg");
+	public static Property additText = new Property(Marking.MARKINGADDITIONALTEXTPREFIX + "01", ValueType.String);
+	
+	private Map<String, Object> markingMap = new HashMap<String, Object>();
+	
+	@Before
+	public void buildFax() {
+		markingFile.setIdShort(Marking.MARKINGFILEID);
+		markingName.setValue("0173-1#07-DAA603#004");
+		additText.setValue("text additional");
+		
+		List<ISubmodelElement> elements = new ArrayList<ISubmodelElement>();
+		elements.add(markingFile);
+		elements.add(markingName);
+		elements.add(additText);
+		
+		markingMap.put(Referable.IDSHORT, IDSHORT);
+		markingMap.put(HasSemantics.SEMANTICID, Marking.SEMANTICID);
+		markingMap.put(Property.VALUE, elements);
+	}
+	
+	@Test
+	public void testCreateAsFacade() {
+		Marking markingFromMap = Marking.createAsFacade(markingMap);
+		assertEquals(Marking.SEMANTICID, markingFromMap.getSemanticId());
+		assertEquals(markingFile, markingFromMap.getMarkingFile());
+		assertEquals(markingName, markingFromMap.getMarkingName());
+		assertEquals(Collections.singletonList(additText), markingFromMap.getMarkingAdditionalText());
+		assertEquals(IDSHORT, markingFromMap.getIdShort());
+	}
+	
+	@Test (expected = MetamodelConstructionException.class)
+	public void testCreateAsFacadeExceptionIdShort() {
+		markingMap.remove(Referable.IDSHORT);
+		Marking.createAsFacade(markingMap);
+	}
+	
+	@SuppressWarnings("unchecked")
+	@Test (expected = ResourceNotFoundException.class)
+	public void testCreateAsFacadeExceptionMarkingName() {
+		List<ISubmodelElement> elements = (List<ISubmodelElement>)markingMap.get(Property.VALUE);
+		elements.remove(markingName);
+		Marking.createAsFacade(markingMap);
+	}
+
+	@SuppressWarnings("unchecked")
+	@Test (expected = ResourceNotFoundException.class)
+	public void testCreateAsFacadeExceptionMarkingFile() {
+		List<ISubmodelElement> elements = (List<ISubmodelElement>)markingMap.get(Property.VALUE);
+		elements.remove(markingFile);
+		Marking.createAsFacade(markingMap);
+	}
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/markings/TestMarkings.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/markings/TestMarkings.java
new file mode 100644
index 0000000..fc2a613
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/markings/TestMarkings.java
@@ -0,0 +1,87 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.submodel.types.digitalnameplate.submodelelementcollections.markings;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.types.digitalnameplate.submodelelementcollections.markings.Marking;
+import org.eclipse.basyx.submodel.types.digitalnameplate.submodelelementcollections.markings.Markings;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasSemantics;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
+
+/**
+ * Tests createAsFacade and isValid of {@link Markings} for their
+ * correctness
+ * 
+ * @author haque
+ *
+ */
+public class TestMarkings {
+	public static final String IDSHORT = "Markings";
+	public static List<Marking> markings;
+	public static Marking marking;
+
+	private Map<String, Object> markingsMap = new HashMap<String, Object>();
+	
+	@Before
+	public void initMarkings() {
+		TestMarking.markingFile.setIdShort(Marking.MARKINGFILEID);
+		TestMarking.markingName.setValue("0173-1#07-DAA603#004");
+		marking = new Marking(TestMarking.IDSHORT, TestMarking.markingName, TestMarking.markingFile);
+		marking.setParent(new Reference(new Key(KeyElements.SUBMODELELEMENTCOLLECTION, true, IDSHORT, IdentifierType.IRDI)));
+		markings = new ArrayList<Marking>();
+		markings.add(marking);
+		
+		markingsMap.put(Referable.IDSHORT, IDSHORT);
+		markingsMap.put(Property.VALUE, markings);
+		markingsMap.put(HasSemantics.SEMANTICID, Markings.SEMANTICID);
+	}
+	
+	@Test
+	public void testCreateAsFacade() {
+		Markings markingsFromMap = Markings.createAsFacade(markingsMap);
+		assertEquals(Markings.SEMANTICID, markingsFromMap.getSemanticId());
+		assertEquals(markings, markingsFromMap.getMarking());
+		assertEquals(IDSHORT, markingsFromMap.getIdShort());
+	}
+	
+	@Test (expected = MetamodelConstructionException.class)
+	public void testCreateAsFacadeExceptionIdShort() {
+		markingsMap.remove(Referable.IDSHORT);
+		Markings.createAsFacade(markingsMap);
+	}
+	
+	@Test (expected = MetamodelConstructionException.class)
+	public void testCreateAsFacadeExceptionNullMarkings() {
+		markingsMap.remove(Property.VALUE);
+		Markings.createAsFacade(markingsMap);
+	}
+	
+	@Test (expected = MetamodelConstructionException.class)
+	public void testCreateAsFacadeExceptionEmptyMarkings() {
+		markingsMap.put(Property.VALUE, new ArrayList<Marking>());
+		Markings.createAsFacade(markingsMap);
+	}
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/technicaldata/TestTechnicalDataSubmodel.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/technicaldata/TestTechnicalDataSubmodel.java
new file mode 100644
index 0000000..c8e70ce
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/technicaldata/TestTechnicalDataSubmodel.java
@@ -0,0 +1,117 @@
+/*******************************************************************************
+* Copyright (C) 2021 the Eclipse BaSyx Authors
+* 
+* This program and the accompanying materials are made
+* available under the terms of the Eclipse Public License 2.0
+* which is available at https://www.eclipse.org/legal/epl-2.0/
+
+* 
+* SPDX-License-Identifier: EPL-2.0
+******************************************************************************/
+
+package org.eclipse.basyx.testsuite.regression.submodel.types.technicaldata;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.map.Submodel;
+import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasSemantics;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Identifiable;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangString;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangStrings;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.submodel.types.technicaldata.TechnicalDataSubmodel;
+import org.eclipse.basyx.submodel.types.technicaldata.submodelelementcollections.furtherinformation.FurtherInformation;
+import org.eclipse.basyx.submodel.types.technicaldata.submodelelementcollections.generalinformation.GeneralInformation;
+import org.eclipse.basyx.submodel.types.technicaldata.submodelelementcollections.productclassifications.ProductClassifications;
+import org.eclipse.basyx.submodel.types.technicaldata.submodelelementcollections.technicalproperties.TechnicalProperties;
+import org.eclipse.basyx.testsuite.regression.submodel.types.technicaldata.generalinformation.TestGeneralInformation;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests createAsFacade and isValid of {@link TechnicalDataSubmodel} for their
+ * correctness
+ * 
+ * @author haque
+ *
+ */
+public class TestTechnicalDataSubmodel {
+	public static GeneralInformation generalInformation = new GeneralInformation(TestGeneralInformation.manufacturerName, TestGeneralInformation.designation, TestGeneralInformation.partNumber, TestGeneralInformation.orderCode);
+	public static ProductClassifications productClassifications = new ProductClassifications(TechnicalDataSubmodel.PRODUCTCLASSIFICATIONSID);
+	public static TechnicalProperties technicalProperties = new TechnicalProperties(TechnicalDataSubmodel.TECHNICALPROPERTIESID);
+	public static FurtherInformation furtherInformation = new FurtherInformation(new Property(FurtherInformation.VALIDDATEID, ValueType.DateTime));
+	
+	public static Identifier identifier = new Identifier(IdentifierType.IRI, "http://admin-shell.io/ZVEI/TechnicalData/Submodel/1/1");
+	private Map<String, Object> submodelMap = new HashMap<String, Object>();
+	
+	@Before
+	public void buildFax() {
+		TestGeneralInformation.manufacturerName.setValue("Example Company");
+		TestGeneralInformation.designation.setValue(new LangStrings(new LangString("de", "Elektrischer Energie Beschleuniger")));
+		TestGeneralInformation.partNumber.setValue("A123-456");
+		TestGeneralInformation.orderCode.setValue("EEA-EX-200-S/47-Q3");
+
+		List<ISubmodelElement> elements = new ArrayList<ISubmodelElement>();
+		elements.add(generalInformation);
+		elements.add(furtherInformation);
+		elements.add(productClassifications);
+		elements.add(technicalProperties);
+		
+		submodelMap.put(Referable.IDSHORT, TechnicalDataSubmodel.SUBMODELID);
+		submodelMap.put(HasSemantics.SEMANTICID, TechnicalDataSubmodel.SEMANTICID);
+		submodelMap.put(Submodel.SUBMODELELEMENT, elements);
+		submodelMap.put(Identifiable.IDENTIFICATION, identifier);
+	}
+
+	@Test
+	public void testCreateAsFacade() {
+		TechnicalDataSubmodel submodelFromMap = TechnicalDataSubmodel.createAsFacade(submodelMap);
+		assertEquals(TechnicalDataSubmodel.SEMANTICID, submodelFromMap.getSemanticId());
+		assertEquals(generalInformation, submodelFromMap.getGeneralInformation());
+		assertEquals(furtherInformation, submodelFromMap.getFurtherInformation());
+		assertEquals(technicalProperties, submodelFromMap.getTechnicalProperties());
+		assertEquals(productClassifications, submodelFromMap.getProductClassifications());
+		assertEquals(TechnicalDataSubmodel.SUBMODELID, submodelFromMap.getIdShort());
+		assertEquals(identifier, submodelFromMap.getIdentification());
+	}
+	
+	@Test (expected = MetamodelConstructionException.class)
+	public void testCreateAsFacadeExceptionIdShort() {
+		submodelMap.remove(Referable.IDSHORT);
+		TechnicalDataSubmodel.createAsFacade(submodelMap);
+	}
+	
+	@Test (expected = MetamodelConstructionException.class)
+	public void testCreateAsFacadeExceptionIdentifier() {
+		submodelMap.remove(Identifiable.IDENTIFICATION);
+		TechnicalDataSubmodel.createAsFacade(submodelMap);
+	}
+	
+	@SuppressWarnings("unchecked")
+	@Test (expected = ResourceNotFoundException.class)
+	public void testCreateAsFacadeExceptionGeneralInfo() {
+		List<ISubmodelElement> elements = (List<ISubmodelElement>)submodelMap.get(Submodel.SUBMODELELEMENT);
+		elements.remove(generalInformation);
+		TechnicalDataSubmodel.createAsFacade(submodelMap);
+	}
+	
+	@SuppressWarnings("unchecked")
+	@Test (expected = ResourceNotFoundException.class)
+	public void testCreateAsFacadeExceptionTechnicalProp() {
+		List<ISubmodelElement> elements = (List<ISubmodelElement>)submodelMap.get(Submodel.SUBMODELELEMENT);
+		elements.remove(technicalProperties);
+		TechnicalDataSubmodel.createAsFacade(submodelMap);
+	}
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/technicaldata/furtherinformation/TestFurtherInformation.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/technicaldata/furtherinformation/TestFurtherInformation.java
new file mode 100644
index 0000000..b82ed47
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/technicaldata/furtherinformation/TestFurtherInformation.java
@@ -0,0 +1,81 @@
+/*******************************************************************************
+* Copyright (C) 2021 the Eclipse BaSyx Authors
+* 
+* This program and the accompanying materials are made
+* available under the terms of the Eclipse Public License 2.0
+* which is available at https://www.eclipse.org/legal/epl-2.0/
+
+* 
+* SPDX-License-Identifier: EPL-2.0
+******************************************************************************/
+
+package org.eclipse.basyx.testsuite.regression.submodel.types.technicaldata.furtherinformation;
+
+import static org.junit.Assert.assertEquals;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasSemantics;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangString;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangStrings;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.MultiLanguageProperty;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.submodel.types.technicaldata.submodelelementcollections.furtherinformation.FurtherInformation;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests createAsFacade and isValid of {@link FurtherInformation} for their
+ * correctness
+ * 
+ * @author haque
+ *
+ */
+public class TestFurtherInformation {
+	public static MultiLanguageProperty statement = new MultiLanguageProperty(FurtherInformation.TEXTSTATEMENTPREFIX + "01");
+	public static Property validDate = new Property(FurtherInformation.VALIDDATEID, ValueType.DateTime);
+	private Map<String, Object> furtherInfoMap = new HashMap<String, Object>();
+	
+	@Before
+	public void init() {
+		statement.setValue(new LangStrings(new LangString("DE", "test statement")));
+		validDate.setValue("01-01-2021");
+		List<ISubmodelElement> elements = new ArrayList<ISubmodelElement>();
+		elements.add(statement);
+		elements.add(validDate);
+		furtherInfoMap.put(Referable.IDSHORT, FurtherInformation.IDSHORT);
+		furtherInfoMap.put(HasSemantics.SEMANTICID, FurtherInformation.SEMANTICID);
+		furtherInfoMap.put(Property.VALUE, elements);
+	}
+	
+	@Test
+	public void testCreateAsFacade() {
+		FurtherInformation infoFromMap = FurtherInformation.createAsFacade(furtherInfoMap);
+		assertEquals(FurtherInformation.SEMANTICID, infoFromMap.getSemanticId());
+		assertEquals(Collections.singletonList(statement), infoFromMap.getStatements());
+		assertEquals(validDate, infoFromMap.getValidDate());
+		assertEquals(FurtherInformation.IDSHORT, infoFromMap.getIdShort());
+	}
+	
+	@Test (expected = MetamodelConstructionException.class)
+	public void testCreateAsFacadeExceptionIdShort() {
+		furtherInfoMap.remove(Referable.IDSHORT);
+		FurtherInformation.createAsFacade(furtherInfoMap);
+	}
+	
+	@Test (expected = ResourceNotFoundException.class)
+	public void testCreateAsFacadeExceptionValidDate() {
+		List<ISubmodelElement> newElements = new ArrayList<ISubmodelElement>();
+		newElements.add(statement);
+		furtherInfoMap.put(Property.VALUE, newElements);
+		FurtherInformation.createAsFacade(furtherInfoMap);
+	}
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/technicaldata/generalinformation/TestGeneralInformation.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/technicaldata/generalinformation/TestGeneralInformation.java
new file mode 100644
index 0000000..a54c763
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/technicaldata/generalinformation/TestGeneralInformation.java
@@ -0,0 +1,127 @@
+/*******************************************************************************
+* Copyright (C) 2021 the Eclipse BaSyx Authors
+* 
+* This program and the accompanying materials are made
+* available under the terms of the Eclipse Public License 2.0
+* which is available at https://www.eclipse.org/legal/epl-2.0/
+
+* 
+* SPDX-License-Identifier: EPL-2.0
+******************************************************************************/
+
+package org.eclipse.basyx.testsuite.regression.submodel.types.technicaldata.generalinformation;
+
+import static org.junit.Assert.assertEquals;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasSemantics;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangString;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangStrings;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.File;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.MultiLanguageProperty;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.submodel.types.technicaldata.submodelelementcollections.generalinformation.GeneralInformation;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests createAsFacade and isValid of {@link GeneralInformation} for their
+ * correctness
+ * 
+ * @author haque
+ *
+ */
+public class TestGeneralInformation {
+	public static Property manufacturerName = new Property(GeneralInformation.MANUFACTURERNAMEID, ValueType.String);
+	public static File manufacturerLogo = new File("image/png");
+	public static MultiLanguageProperty designation = new MultiLanguageProperty(GeneralInformation.MANUFACTURERPRODUCTDESIGNATIONID);
+	public static Property partNumber = new Property(GeneralInformation.MANUFACTURERPARTNUMBERID, ValueType.String);
+	public static Property orderCode = new Property(GeneralInformation.MANUFACTURERORDERCODEID, ValueType.String);
+	public static File image = new File("image/jpg");
+	
+	private Map<String, Object> InfoMap = new HashMap<String, Object>();
+	
+	@Before
+	public void init() {
+		manufacturerName.setValue("Example Company");
+		manufacturerLogo.setIdShort(GeneralInformation.MANUFACTURERLOGOID);
+		manufacturerLogo.setValue("/aasx/TechnicalData/logo.png");
+		designation.setValue(new LangStrings(new LangString("de", "Elektrischer Energie Beschleuniger")));
+		partNumber.setValue("A123-456");
+		orderCode.setValue("EEA-EX-200-S/47-Q3");
+		image.setIdShort(GeneralInformation.PRODUCTIMAGEPREFIX + "01");
+		image.setValue("/aasx/TechnicalData/ ProdFromTop.jpg");
+		
+		List<ISubmodelElement> elements = new ArrayList<ISubmodelElement>();
+		elements.add(manufacturerName);
+		elements.add(manufacturerLogo);
+		elements.add(designation);
+		elements.add(partNumber);
+		elements.add(orderCode);
+		elements.add(image);
+		
+		InfoMap.put(Referable.IDSHORT, GeneralInformation.IDSHORT);
+		InfoMap.put(HasSemantics.SEMANTICID, GeneralInformation.SEMANTICID);
+		InfoMap.put(Property.VALUE, elements);
+	}
+	
+	@Test
+	public void testCreateAsFacade() {
+		GeneralInformation infoFromMap = GeneralInformation.createAsFacade(InfoMap);
+		assertEquals(GeneralInformation.SEMANTICID, infoFromMap.getSemanticId());
+		assertEquals(Collections.singletonList(image), infoFromMap.getProductImages());
+		assertEquals(manufacturerName, infoFromMap.getManufacturerName());
+		assertEquals(manufacturerLogo, infoFromMap.getManufacturerLogo());
+		assertEquals(designation, infoFromMap.getManufacturerProductDesignation());
+		assertEquals(partNumber, infoFromMap.getManufacturerPartNumber());
+		assertEquals(orderCode, infoFromMap.getManufacturerOrderCode());
+		assertEquals(GeneralInformation.IDSHORT, infoFromMap.getIdShort());
+	}
+	
+	@Test (expected = MetamodelConstructionException.class)
+	public void testCreateAsFacadeExceptionIdShort() {
+		InfoMap.remove(Referable.IDSHORT);
+		GeneralInformation.createAsFacade(InfoMap);
+	}
+	
+	@Test (expected = ResourceNotFoundException.class)
+	@SuppressWarnings("unchecked")
+	public void testCreateAsFacadeExceptionName() {
+		List<ISubmodelElement> elements = (List<ISubmodelElement>)InfoMap.get(Property.VALUE);
+		elements.remove(manufacturerName);
+		GeneralInformation.createAsFacade(InfoMap);
+	}
+	
+	@Test (expected = ResourceNotFoundException.class)
+	@SuppressWarnings("unchecked")
+	public void testCreateAsFacadeExceptionDesignation() {
+		List<ISubmodelElement> elements = (List<ISubmodelElement>)InfoMap.get(Property.VALUE);
+		elements.remove(designation);
+		GeneralInformation.createAsFacade(InfoMap);
+	}
+	
+	@Test (expected = ResourceNotFoundException.class)
+	@SuppressWarnings("unchecked")
+	public void testCreateAsFacadeExceptionPartNumber() {
+		List<ISubmodelElement> elements = (List<ISubmodelElement>)InfoMap.get(Property.VALUE);
+		elements.remove(partNumber);
+		GeneralInformation.createAsFacade(InfoMap);
+	}
+	
+	@Test (expected = ResourceNotFoundException.class)
+	@SuppressWarnings("unchecked")
+	public void testCreateAsFacadeExceptionOrderCode() {
+		List<ISubmodelElement> elements = (List<ISubmodelElement>)InfoMap.get(Property.VALUE);
+		elements.remove(orderCode);
+		GeneralInformation.createAsFacade(InfoMap);
+	}
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/technicaldata/productclassifications/TestProductClassificationItem.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/technicaldata/productclassifications/TestProductClassificationItem.java
new file mode 100644
index 0000000..8175a46
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/technicaldata/productclassifications/TestProductClassificationItem.java
@@ -0,0 +1,93 @@
+/*******************************************************************************
+* Copyright (C) 2021 the Eclipse BaSyx Authors
+* 
+* This program and the accompanying materials are made
+* available under the terms of the Eclipse Public License 2.0
+* which is available at https://www.eclipse.org/legal/epl-2.0/
+
+* 
+* SPDX-License-Identifier: EPL-2.0
+******************************************************************************/
+
+package org.eclipse.basyx.testsuite.regression.submodel.types.technicaldata.productclassifications;
+
+import static org.junit.Assert.assertEquals;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasSemantics;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.submodel.types.technicaldata.submodelelementcollections.productclassifications.ProductClassificationItem;
+import org.eclipse.basyx.submodel.types.technicaldata.submodelelementcollections.productclassifications.ProductClassifications;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests createAsFacade and isValid of {@link ProductClassificationItem} for their
+ * correctness
+ * 
+ * @author haque
+ *
+ */
+public class TestProductClassificationItem {
+	public static Property classificationSystem = new Property(ProductClassificationItem.PRODUCTCLASSIFICATIONSYSTEMID, ValueType.String);
+	public static Property version = new Property(ProductClassificationItem.CLASSIFICATIONSYSTEMVERSIONID, ValueType.String);
+	public static Property productClass = new Property(ProductClassificationItem.PRODUCTCLASSID, ValueType.String);
+	
+	private Map<String, Object> classificationMap = new HashMap<String, Object>();
+	
+	@Before
+	public void init() {
+		classificationSystem.setValue("ECLASS");
+		version.setValue("9.0 (BASIC)");
+		productClass.setValue("27-01-88-77");
+		
+		List<ISubmodelElement> elements = new ArrayList<ISubmodelElement>();
+		elements.add(classificationSystem);
+		elements.add(version);
+		elements.add(productClass);
+		
+		classificationMap.put(Referable.IDSHORT, ProductClassifications.PRODUCTCLASSIFICATIONITEMPREFIX + "01");
+		classificationMap.put(HasSemantics.SEMANTICID, ProductClassificationItem.SEMANTICID);
+		classificationMap.put(Property.VALUE, elements);
+	}
+	
+	@Test
+	public void testCreateAsFacade() {
+		ProductClassificationItem classificationFromMap = ProductClassificationItem.createAsFacade(classificationMap);
+		assertEquals(ProductClassificationItem.SEMANTICID, classificationFromMap.getSemanticId());
+		assertEquals(classificationSystem, classificationFromMap.getProductClassificationSystem());
+		assertEquals(version, classificationFromMap.getClassificationSystemVersion());
+		assertEquals(productClass, classificationFromMap.getProductClassId());
+		assertEquals(ProductClassifications.PRODUCTCLASSIFICATIONITEMPREFIX + "01", classificationFromMap.getIdShort());
+	}
+	
+	@Test (expected = MetamodelConstructionException.class)
+	public void testCreateAsFacadeExceptionIdShort() {
+		classificationMap.remove(Referable.IDSHORT);
+		ProductClassificationItem.createAsFacade(classificationMap);
+	}
+	
+	@Test (expected = ResourceNotFoundException.class)
+	@SuppressWarnings("unchecked")
+	public void testCreateAsFacadeExceptionProductClassificationSystem() {
+		List<ISubmodelElement> elements = (List<ISubmodelElement>)classificationMap.get(Property.VALUE);
+		elements.remove(classificationSystem);
+		ProductClassificationItem.createAsFacade(classificationMap);
+	}
+	
+	@Test (expected = ResourceNotFoundException.class)
+	@SuppressWarnings("unchecked")
+	public void testCreateAsFacadeExceptionProductClassId() {
+		List<ISubmodelElement> elements = (List<ISubmodelElement>)classificationMap.get(Property.VALUE);
+		elements.remove(productClass);
+		ProductClassificationItem.createAsFacade(classificationMap);
+	}
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/technicaldata/productclassifications/TestProductClassifications.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/technicaldata/productclassifications/TestProductClassifications.java
new file mode 100644
index 0000000..1069b98
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/technicaldata/productclassifications/TestProductClassifications.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+* Copyright (C) 2021 the Eclipse BaSyx Authors
+* 
+* This program and the accompanying materials are made
+* available under the terms of the Eclipse Public License 2.0
+* which is available at https://www.eclipse.org/legal/epl-2.0/
+
+* 
+* SPDX-License-Identifier: EPL-2.0
+******************************************************************************/
+
+package org.eclipse.basyx.testsuite.regression.submodel.types.technicaldata.productclassifications;
+
+import static org.junit.Assert.assertEquals;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasSemantics;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.types.technicaldata.submodelelementcollections.productclassifications.ProductClassificationItem;
+import org.eclipse.basyx.submodel.types.technicaldata.submodelelementcollections.productclassifications.ProductClassifications;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests createAsFacade and isValid of {@link ProductClassifications} for their
+ * correctness
+ * 
+ * @author haque
+ *
+ */
+public class TestProductClassifications {
+	public static ProductClassificationItem productClassificationItem = new ProductClassificationItem(ProductClassifications.PRODUCTCLASSIFICATIONITEMPREFIX + "01", TestProductClassificationItem.classificationSystem, TestProductClassificationItem.productClass);
+	
+	private Map<String, Object> classificationMap = new HashMap<String, Object>();
+	
+	@Before
+	public void init() {
+		List<ISubmodelElement> elements = new ArrayList<ISubmodelElement>();
+		elements.add(productClassificationItem);
+		
+		classificationMap.put(Referable.IDSHORT, ProductClassifications.IDSHORT);
+		classificationMap.put(HasSemantics.SEMANTICID, ProductClassifications.SEMANTICID);
+		classificationMap.put(Property.VALUE, elements);
+	}
+	
+	@Test
+	public void testCreateAsFacade() {
+		ProductClassifications classificationFromMap = ProductClassifications.createAsFacade(classificationMap);
+		assertEquals(ProductClassifications.SEMANTICID, classificationFromMap.getSemanticId());
+		assertEquals(ProductClassifications.IDSHORT, classificationFromMap.getIdShort());
+		assertEquals(Collections.singletonList(productClassificationItem), classificationFromMap.getProductClassificationItems());
+	}
+	
+	@Test (expected = MetamodelConstructionException.class)
+	public void testCreateAsFacadeExceptionIdShort() {
+		classificationMap.remove(Referable.IDSHORT);
+		ProductClassifications.createAsFacade(classificationMap);
+	}
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/technicaldata/technicalproperties/TestTechnicalProperties.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/technicaldata/technicalproperties/TestTechnicalProperties.java
new file mode 100644
index 0000000..7dd6666
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/technicaldata/technicalproperties/TestTechnicalProperties.java
@@ -0,0 +1,86 @@
+/*******************************************************************************
+* Copyright (C) 2021 the Eclipse BaSyx Authors
+* 
+* This program and the accompanying materials are made
+* available under the terms of the Eclipse Public License 2.0
+* which is available at https://www.eclipse.org/legal/epl-2.0/
+
+* 
+* SPDX-License-Identifier: EPL-2.0
+******************************************************************************/
+
+package org.eclipse.basyx.testsuite.regression.submodel.types.technicaldata.technicalproperties;
+
+import static org.junit.Assert.assertEquals;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasSemantics;
+import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElement;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType;
+import org.eclipse.basyx.submodel.types.technicaldata.submodelelementcollections.technicalproperties.TechnicalProperties;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests createAsFacade and isValid of {@link TestTechnicalProperties} for their
+ * correctness
+ * 
+ * @author haque
+ *
+ */
+public class TestTechnicalProperties {
+	public static SubmodelElementCollection mainSection = new SubmodelElementCollection(TechnicalProperties.MAINSECTIONPREFIX + "01");
+	public static SubmodelElementCollection subSection = new SubmodelElementCollection(TechnicalProperties.SUBSECTIONPREFIX + "01");
+	public static SubmodelElement arbitrary1 = new Property("arbitraryId1", ValueType.String);
+	public static SubmodelElement arbitrary2 = new Property("arbitraryId2", ValueType.String);
+	
+	private Map<String, Object> technicalMap = new HashMap<String, Object>();
+	
+	@Before
+	public void init() {
+		mainSection.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, TechnicalProperties.MAINSECTIONID, IdentifierType.IRDI)));
+		subSection.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, TechnicalProperties.SUBSECTIONID, IdentifierType.IRDI)));
+		arbitrary1.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "anyid", IdentifierType.IRDI)));
+		arbitrary2.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, TechnicalProperties.SMENOTDESCRIBEDID, IdentifierType.IRDI)));
+
+		List<ISubmodelElement> elements = new ArrayList<ISubmodelElement>();
+		elements.add(mainSection);
+		elements.add(subSection);
+		elements.add(arbitrary1);
+		elements.add(arbitrary2);
+		
+		technicalMap.put(Referable.IDSHORT, TechnicalProperties.IDSHORT);
+		technicalMap.put(HasSemantics.SEMANTICID, TechnicalProperties.SEMANTICID);
+		technicalMap.put(Property.VALUE, elements);
+	}
+	
+	@Test
+	public void testCreateAsFacade() {
+		TechnicalProperties propFromMap = TechnicalProperties.createAsFacade(technicalMap);
+		assertEquals(TechnicalProperties.SEMANTICID, propFromMap.getSemanticId());
+		assertEquals(TechnicalProperties.IDSHORT, propFromMap.getIdShort());
+		assertEquals(Collections.singletonList(mainSection), propFromMap.getMainSections());
+		assertEquals(Collections.singletonList(subSection), propFromMap.getSubSections());
+		assertEquals(Collections.singletonList(arbitrary1), propFromMap.getArbitrary());
+		assertEquals(Collections.singletonList(arbitrary2), propFromMap.getSMENotDescribedBySemanticId());
+	}
+	
+	@Test (expected = MetamodelConstructionException.class)
+	public void testCreateAsFacadeExceptionIdShort() {
+		technicalMap.remove(Referable.IDSHORT);
+		TechnicalProperties.createAsFacade(technicalMap);
+	}
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/coder/json/IBasyxConnectorFacade.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/coder/json/IBasyxConnectorFacade.java
index 9ac52a9..e065250 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/coder/json/IBasyxConnectorFacade.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/coder/json/IBasyxConnectorFacade.java
@@ -1,13 +1,22 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.vab.coder.json;
 
-import java.io.FileNotFoundException;
+import java.io.ByteArrayOutputStream;
+import java.io.UnsupportedEncodingException;
+import java.nio.charset.StandardCharsets;
 
 import org.eclipse.basyx.vab.coder.json.provider.JSONProvider;
 import org.eclipse.basyx.vab.exception.provider.ProviderException;
 import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
 import org.eclipse.basyx.vab.protocol.api.IBaSyxConnector;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 /**
  * This class is required for Meta-protocol integration testing. It makes
@@ -20,8 +29,6 @@
  */
 public class IBasyxConnectorFacade<T extends IModelProvider> implements IBaSyxConnector {
 	
-	private static Logger logger = LoggerFactory.getLogger(IBasyxConnectorFacade.class);
-	
 	JSONProvider<T> provider;
 	
 	public IBasyxConnectorFacade(JSONProvider<T> p) {
@@ -33,19 +40,15 @@
 	 * message
 	 */
 	@Override
-	public String getModelPropertyValue(String path) {
-		try {
-			PrintWriterStub outputstream = new PrintWriterStub("test.txt", "ignore");
+	public String getValue(String path) {
+		ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+		provider.processBaSysGet(path, outputStream);
 		
-			provider.processBaSysGet(path, outputstream);
-			
-			return outputstream.getResult();
-		} catch (FileNotFoundException e) {
-			logger.error("[TEST] Exception in getModelPropertyValue", e);
+		try {
+			return outputStream.toString(StandardCharsets.UTF_8.displayName());
+		} catch (UnsupportedEncodingException e) {
+			throw new RuntimeException("Should not happen...");
 		}
-
-		// This should never happen
-		return null;		
 	}
 
 	/**
@@ -53,17 +56,15 @@
 	 * message
 	 */
 	@Override
-	public String setModelPropertyValue(String path, String newValue) throws ProviderException {
-		try {
-			PrintWriterStub outputstream = new PrintWriterStub("test.txt", "ignore");
+	public String setValue(String path, String newValue) throws ProviderException {
+		ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+		provider.processBaSysSet(path, newValue, outputStream);
 		
-			provider.processBaSysSet(path, newValue, outputstream);
-			
-			return outputstream.getResult();
-		} catch (FileNotFoundException e) {
-			logger.error("[TEST] Exception in setModelPropertyValue", e);
+		try {
+			return outputStream.toString(StandardCharsets.UTF_8.displayName());
+		} catch (UnsupportedEncodingException e) {
+			throw new RuntimeException("Should not happen...");
 		}
-		return null;		
 	}
 
 	/**
@@ -72,16 +73,14 @@
 	 */
 	@Override
 	public String createValue(String path, String newEntity) throws ProviderException {
-		try {
-			PrintWriterStub outputstream = new PrintWriterStub("test.txt", "ignore");
+		ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+		provider.processBaSysCreate(path, newEntity, outputStream);
 		
-			provider.processBaSysCreate(path, newEntity, outputstream);
-			
-			return outputstream.getResult();
-		} catch (FileNotFoundException e) {
-			logger.error("[TEST] Exception in createValue", e);
-		}
-		return null;		
+		try {
+			return outputStream.toString(StandardCharsets.UTF_8.displayName());
+		} catch (UnsupportedEncodingException e) {
+			throw new RuntimeException("Should not happen...");
+		}	
 	}
 
 	/**
@@ -90,17 +89,15 @@
 	 */
 	@Override
 	public String deleteValue(String path) throws ProviderException {
-		try {
-			PrintWriterStub outputstream = new PrintWriterStub("test.txt", "ignore");
+		ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+		String nullParam = "null";
+		provider.processBaSysDelete(path, nullParam, outputStream);
 		
-			String nullParam = "null";
-			provider.processBaSysDelete(path, nullParam, outputstream);
-			
-			return outputstream.getResult();
-		} catch (FileNotFoundException e) {
-			logger.error("[TEST] Exception in deleteValue", e);
+		try {
+			return outputStream.toString(StandardCharsets.UTF_8.displayName());
+		} catch (UnsupportedEncodingException e) {
+			throw new RuntimeException("Should not happen...");
 		}
-		return null;
 	}
 
 	/**
@@ -109,16 +106,14 @@
 	 */
 	@Override
 	public String deleteValue(String path, String obj) throws ProviderException {
-		try {
-			PrintWriterStub outputstream = new PrintWriterStub("test.txt", "ignore");
+		ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+		provider.processBaSysDelete(path, obj, outputStream);
 		
-			provider.processBaSysDelete(path, obj, outputstream);
-			
-			return outputstream.getResult();
-		} catch (FileNotFoundException e) {
-			logger.error("[TEST] Exception in deleteValue", e);
+		try {
+			return outputStream.toString(StandardCharsets.UTF_8.displayName());
+		} catch (UnsupportedEncodingException e) {
+			throw new RuntimeException("Should not happen...");
 		}
-		return null;
 	}
 
 	/**
@@ -127,17 +122,18 @@
 	 */
 	@Override
 	public String invokeOperation(String path, String jsonObject) throws ProviderException {
-		try {
-			PrintWriterStub outputstream = new PrintWriterStub("test.txt", "ignore");
+		ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+		provider.processBaSysInvoke(path, jsonObject, outputStream);
 		
-			provider.processBaSysInvoke(path, jsonObject, outputstream);
-			
-			return outputstream.getResult();
-		} catch (FileNotFoundException e) {
-			logger.error("[TEST] Exception in invokeOperation", e);
+		try {
+			return outputStream.toString(StandardCharsets.UTF_8.displayName());
+		} catch (UnsupportedEncodingException e) {
+			throw new RuntimeException("Should not happen...");
 		}
-		return null;
 	}
 
-	
+	@Override
+	public String getEndpointRepresentation(String path) {
+		return "test://" + path;
+	}
 }
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/coder/json/PrintWriterStub.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/coder/json/PrintWriterStub.java
index e5d0c12..392ba46 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/coder/json/PrintWriterStub.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/coder/json/PrintWriterStub.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.vab.coder.json;
 
 import static org.junit.Assert.assertTrue;
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/coder/json/TestJSONConnectorProviderIntegration.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/coder/json/TestJSONConnectorProviderIntegration.java
index b263fa2..f6ed4f9 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/coder/json/TestJSONConnectorProviderIntegration.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/coder/json/TestJSONConnectorProviderIntegration.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.vab.coder.json;
 
 import org.eclipse.basyx.testsuite.regression.vab.modelprovider.SimpleVABElement;
@@ -8,7 +17,7 @@
 import org.eclipse.basyx.vab.manager.VABConnectionManager;
 import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
 import org.eclipse.basyx.vab.modelprovider.map.VABMapProvider;
-import org.eclipse.basyx.vab.protocol.api.ConnectorProvider;
+import org.eclipse.basyx.vab.protocol.api.ConnectorFactory;
 
 /**
  * Test JSONConnector against JSONProvider
@@ -19,7 +28,7 @@
 public class TestJSONConnectorProviderIntegration extends TestProvider {
 
 	protected VABConnectionManager connManager = new VABConnectionManager(new TestsuiteDirectory(),
-			new ConnectorProvider() {
+			new ConnectorFactory() {
 
 				@Override
 				protected IModelProvider createProvider(String addr) {
@@ -46,4 +55,4 @@
 	protected VABConnectionManager getConnectionManager() {
 		return connManager;
 	}
-}
\ No newline at end of file
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/coder/json/TestJson.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/coder/json/TestJson.java
index f42432d..d1d4735 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/coder/json/TestJson.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/coder/json/TestJson.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.vab.coder.json;
 
 import static org.junit.Assert.assertEquals;
@@ -7,6 +16,7 @@
 import java.io.IOException;
 import java.io.ObjectOutputStream;
 import java.io.Serializable;
+import java.math.BigInteger;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Base64;
@@ -37,7 +47,7 @@
  */
 public class TestJson {
 
-	GSONTools tools = new GSONTools(new DefaultTypeFactory());
+	GSONTools tools = new GSONTools(new DefaultTypeFactory(), false, false);
 
 	/**
 	 * Tests if a double is correctly (de-)serialized
@@ -61,6 +71,13 @@
 		assertEquals(primitive.toString(), tools.serialize(12));
 	}
 
+	@Test
+	public void testBigInteger() {
+		BigInteger dec = new BigInteger("10000000000000000000000000000000000000");
+		BigInteger deserialized = (BigInteger) tools.deserialize(tools.serialize(dec));
+		assertEquals(dec, deserialized);
+	}
+
 	/**
 	 * Tests if a boolean is correctly (de-)serialized
 	 */
@@ -301,6 +318,32 @@
 
 		assertEquals(testFunction.apply(5), deserialized.apply(5));
 	}
+	
+	/**
+	 * Tests if null values and empty arrays are getting removed successfully
+	 * with remove flag on
+	 * 
+	 */
+	@Test
+	public void testSerializeWithRemoveFlagsOn() throws IOException {
+		GSONTools toolWithRemoveFlagOn = new GSONTools(new DefaultTypeFactory(), true, true);
+		Map<String, Object> expected = new HashMap<>();
+		Map<String, Object> a = new HashMap<>();
+		a.put("x", 123);
+		expected.put("a", a);
+		expected.put("b", "123");
+		expected.put("c", null);
+		expected.put("d", new ArrayList<String>());
+		
+		JsonObject aObj = new JsonObject();
+		aObj.add("x", new JsonPrimitive(123));
+		
+		JsonObject expectedObj = new JsonObject();
+		expectedObj.add("a", aObj);
+		expectedObj.add("b", new JsonPrimitive("123"));
+
+		assertEquals(expectedObj.toString(), toolWithRemoveFlagOn.serialize(expected));
+	}
 
 	/**
 	 * Tests for an arbitrary primitive object if it is deserialized correctly
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/directory/memory/TestInMemoryDirectory.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/directory/memory/TestInMemoryDirectory.java
index d918554..9bc9f8d 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/directory/memory/TestInMemoryDirectory.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/directory/memory/TestInMemoryDirectory.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.vab.directory.memory;
 
 import static org.junit.Assert.assertEquals;
@@ -6,8 +15,8 @@
 import java.util.Map;
 
 import org.eclipse.basyx.testsuite.regression.vab.directory.proxy.TestDirectory;
-import org.eclipse.basyx.vab.directory.api.IVABDirectoryService;
-import org.eclipse.basyx.vab.directory.memory.InMemoryDirectory;
+import org.eclipse.basyx.vab.registry.api.IVABRegistryService;
+import org.eclipse.basyx.vab.registry.memory.VABInMemoryRegistry;
 import org.junit.Test;
 
 /**
@@ -19,19 +28,19 @@
 public class TestInMemoryDirectory extends TestDirectory {
 
 	@Override
-	protected IVABDirectoryService getRegistry() {
-		return new InMemoryDirectory();
+	protected IVABRegistryService getRegistry() {
+		return new VABInMemoryRegistry();
 	}
 
 	@Test
 	public void testConstructor() {
-		IVABDirectoryService registry = new InMemoryDirectory(getAddedValues());
+		IVABRegistryService registry = new VABInMemoryRegistry(getAddedValues());
 		testElementsInMap(registry, getAddedValues());
 	}
 
 	@Test
 	public void testAddMappingMultipleKey() {
-		InMemoryDirectory registry = new InMemoryDirectory();
+		VABInMemoryRegistry registry = new VABInMemoryRegistry();
 		String key3 = "key3";
 		String value3 = "value3";
 		String key4 = "key4";
@@ -43,7 +52,7 @@
 		testElementsInMap(registry, map);
 	}
 
-	private void testElementsInMap(IVABDirectoryService registry, Map<String, String> map) {
+	private void testElementsInMap(IVABRegistryService registry, Map<String, String> map) {
 		for (Map.Entry<String, String> entry : map.entrySet()) {
 			assertEquals(entry.getValue(), registry.lookup(entry.getKey()));
 		}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/directory/proxy/TestDirectory.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/directory/proxy/TestDirectory.java
index 5f4fabd..4589c53 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/directory/proxy/TestDirectory.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/directory/proxy/TestDirectory.java
@@ -1,11 +1,20 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.vab.directory.proxy;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.fail;
 
-import org.eclipse.basyx.vab.directory.api.IVABDirectoryService;
 import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.eclipse.basyx.vab.registry.api.IVABRegistryService;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
@@ -19,7 +28,7 @@
  */
 public abstract class TestDirectory {
 	// The registry proxy that is used to access the backend
-	protected final IVABDirectoryService registry = getRegistry();
+	protected final IVABRegistryService registry = getRegistry();
 
 	// Ids and endpoints for registered elements
 	protected String elem1 = "elem1";
@@ -33,7 +42,7 @@
 	 * Getter for the tested registry provider. Tests for actual registry provider
 	 * have to realize this method.
 	 */
-	protected abstract IVABDirectoryService getRegistry();
+	protected abstract IVABRegistryService getRegistry();
 
 	/**
 	 * During setup of the tests, new entries are created in the registry using a
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/directory/restapi/TestDirectoryProvider.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/directory/restapi/TestDirectoryProvider.java
index caaf81a..5a26165 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/directory/restapi/TestDirectoryProvider.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/directory/restapi/TestDirectoryProvider.java
@@ -1,9 +1,18 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.vab.directory.restapi;
 
 import org.eclipse.basyx.testsuite.regression.vab.directory.proxy.TestDirectory;
-import org.eclipse.basyx.vab.directory.api.IVABDirectoryService;
-import org.eclipse.basyx.vab.directory.proxy.VABDirectoryProxy;
-import org.eclipse.basyx.vab.directory.restapi.DirectoryModelProvider;
+import org.eclipse.basyx.vab.registry.api.IVABRegistryService;
+import org.eclipse.basyx.vab.registry.proxy.VABRegistryProxy;
+import org.eclipse.basyx.vab.registry.restapi.VABRegistryModelProvider;
 
 /**
  * Tests the directory provider using the TestDirectory Suite
@@ -14,9 +23,9 @@
 public class TestDirectoryProvider extends TestDirectory {
 
 	@Override
-	protected IVABDirectoryService getRegistry() {
-		DirectoryModelProvider provider = new DirectoryModelProvider();
-		return new VABDirectoryProxy(provider);
+	protected IVABRegistryService getRegistry() {
+		VABRegistryModelProvider provider = new VABRegistryModelProvider();
+		return new VABRegistryProxy(provider);
 	}
 
 }
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/factory/xml/TestVABXmlProviderFactory.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/factory/xml/TestVABXmlProviderFactory.java
index 118616d..6249fa6 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/factory/xml/TestVABXmlProviderFactory.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/factory/xml/TestVABXmlProviderFactory.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.vab.factory.xml;
 
 import static org.junit.Assert.assertEquals;
@@ -21,17 +30,17 @@
 
 		Map<String, String> map;
 
-		assertEquals(provider.getModelPropertyValue("tags/name/"), TestXmlParser.SOME_NAME);
-		assertEquals(provider.getModelPropertyValue("tags/value/"), TestXmlParser.VALUEV);
-		assertEquals(provider.getModelPropertyValue("tags/nestedTags/attrnt"), TestXmlParser.ATTRNT_1_VAL);
-		Iterator<Object> iterator = ((Collection) provider.getModelPropertyValue("tags/nestedTags/nestedTag/"))
+		assertEquals(provider.getValue("tags/name/"), TestXmlParser.SOME_NAME);
+		assertEquals(provider.getValue("tags/value/"), TestXmlParser.VALUEV);
+		assertEquals(provider.getValue("tags/nestedTags/attrnt"), TestXmlParser.ATTRNT_1_VAL);
+		Iterator<Object> iterator = ((Collection) provider.getValue("tags/nestedTags/nestedTag/"))
 				.iterator();
 		assertEquals(TestXmlParser.NESTED_TAG_1, iterator.next());
 		assertEquals(TestXmlParser.NESTED_TAG_2, iterator.next());
 		assertEquals(TestXmlParser.NESTED_TAG_3, iterator.next());
 
 		iterator = ((Collection) provider
-				.getModelPropertyValue("tags/deeplyNestedTagParent/deeplyNestedTagsChild/deeplyNestedTagsLeaf/"))
+				.getValue("tags/deeplyNestedTagParent/deeplyNestedTagsChild/deeplyNestedTagsLeaf/"))
 						.iterator();
 		map = (Map<String, String>) (iterator.next());
 		assertEquals(map.get(TestXmlParser.TEXT), TestXmlParser.DN_TEXT_1);
@@ -41,7 +50,7 @@
 		assertEquals(map.get(TestXmlParser.TEXT), TestXmlParser.DN_TEXT_2);
 		assertEquals(map.get(TestXmlParser.ATTRDN), TestXmlParser.ATTR_2_VAL);
 
-		iterator = ((Collection) provider.getModelPropertyValue("tags/someTag/")).iterator();
+		iterator = ((Collection) provider.getValue("tags/someTag/")).iterator();
 		assertEquals(TestXmlParser.SOME_TEXT_1, iterator.next());
 		assertEquals(TestXmlParser.SOME_TEXT_2, iterator.next());
 		assertEquals(TestXmlParser.SOME_TEXT_3, iterator.next());
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/factory/xml/TestXmlParser.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/factory/xml/TestXmlParser.java
index a50439e..5b59aac 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/factory/xml/TestXmlParser.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/factory/xml/TestXmlParser.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.vab.factory.xml;
 
 import static org.junit.Assert.assertEquals;
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/gateway/ConnectorProviderStub.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/gateway/ConnectorProviderStub.java
index 6b9bcb3..1e48f77 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/gateway/ConnectorProviderStub.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/gateway/ConnectorProviderStub.java
@@ -1,10 +1,19 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.vab.gateway;
 
 import java.util.HashMap;
 import java.util.Map;
 
 import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
-import org.eclipse.basyx.vab.protocol.api.IConnectorProvider;
+import org.eclipse.basyx.vab.protocol.api.IConnectorFactory;
 
 /**
  * A simple ConnectorProvider stub returning connectors based on a String
@@ -13,7 +22,7 @@
  * @author schnicke
  *
  */
-public class ConnectorProviderStub implements IConnectorProvider {
+public class ConnectorProviderStub implements IConnectorFactory {
 	private Map<String, IModelProvider> providerMap = new HashMap<>();
 
 	public void addMapping(String addr, IModelProvider provider) {
@@ -22,6 +31,9 @@
 
 	@Override
 	public IModelProvider getConnector(String addr) {
+		if (!providerMap.containsKey(addr)) {
+			throw new RuntimeException("Unknown addr " + addr);
+		}
 		return providerMap.get(addr);
 	}
 }
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/gateway/TestConnectorProviderMapper.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/gateway/TestConnectorProviderMapper.java
index 885704a..7dac3df 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/gateway/TestConnectorProviderMapper.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/gateway/TestConnectorProviderMapper.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.vab.gateway;
 
 import static org.junit.Assert.assertEquals;
@@ -5,7 +14,7 @@
 
 import org.eclipse.basyx.vab.gateway.ConnectorProviderMapper;
 import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
-import org.eclipse.basyx.vab.protocol.api.IConnectorProvider;
+import org.eclipse.basyx.vab.protocol.api.IConnectorFactory;
 import org.junit.Test;
 
 /**
@@ -28,7 +37,7 @@
 		ConnectorProviderMapper provider = new ConnectorProviderMapper();
 
 		// Add basyx IConnectorProvider stub
-		provider.addConnectorProvider("basyx", new IConnectorProvider() {
+		provider.addConnectorProvider("basyx", new IConnectorFactory() {
 
 			@Override
 			public IModelProvider getConnector(String addr) {
@@ -38,7 +47,7 @@
 		});
 
 		// Add http IConnectorProvider stub
-		provider.addConnectorProvider("http", new IConnectorProvider() {
+		provider.addConnectorProvider("http", new IConnectorFactory() {
 
 			@Override
 			public IModelProvider getConnector(String addr) {
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/gateway/TestDelegatingModelProvider.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/gateway/TestDelegatingModelProvider.java
index 1662f9a..b7ca4f6 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/gateway/TestDelegatingModelProvider.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/gateway/TestDelegatingModelProvider.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.vab.gateway;
 
 import static org.junit.Assert.assertEquals;
@@ -5,7 +14,7 @@
 import org.eclipse.basyx.testsuite.regression.vab.modelprovider.IModelProviderStub;
 import org.eclipse.basyx.vab.gateway.DelegatingModelProvider;
 import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
-import org.eclipse.basyx.vab.protocol.api.IConnectorProvider;
+import org.eclipse.basyx.vab.protocol.api.IConnectorFactory;
 import org.junit.Test;
 
 /**
@@ -31,7 +40,7 @@
 
 		// Create DelegatingModelProvider with a stub writing the address and returning
 		// the IModelProviderStub
-		DelegatingModelProvider provider = new DelegatingModelProvider(new IConnectorProvider() {
+		DelegatingModelProvider provider = new DelegatingModelProvider(new IConnectorFactory() {
 
 			@Override
 			public IModelProvider getConnector(String addr) {
@@ -41,7 +50,7 @@
 		});
 
 		// Get a value based on path
-		provider.getModelPropertyValue(basyx + "//" + rest);
+		provider.getValue(basyx + "//" + rest);
 
 		// Assert that correct address was given to IConnectorProvider
 		assertEquals(address, basyx);
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/gateway/TestGateway.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/gateway/TestGateway.java
index bb1d52b..4b70f98 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/gateway/TestGateway.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/gateway/TestGateway.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.vab.gateway;
 
 import static org.junit.Assert.assertEquals;
@@ -7,18 +16,18 @@
 import java.util.HashMap;
 import java.util.Map;
 
-import org.eclipse.basyx.vab.directory.memory.InMemoryDirectory;
 import org.eclipse.basyx.vab.gateway.ConnectorProviderMapper;
 import org.eclipse.basyx.vab.gateway.DelegatingModelProvider;
 import org.eclipse.basyx.vab.manager.VABConnectionManager;
 import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
 import org.eclipse.basyx.vab.modelprovider.map.VABMapProvider;
-import org.eclipse.basyx.vab.protocol.basyx.connector.BaSyxConnectorProvider;
+import org.eclipse.basyx.vab.protocol.basyx.connector.BaSyxConnectorFactory;
 import org.eclipse.basyx.vab.protocol.basyx.server.BaSyxTCPServer;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
-import org.eclipse.basyx.vab.protocol.http.server.AASHTTPServer;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorFactory;
+import org.eclipse.basyx.vab.protocol.http.server.BaSyxHTTPServer;
 import org.eclipse.basyx.vab.protocol.http.server.BaSyxContext;
 import org.eclipse.basyx.vab.protocol.http.server.VABHTTPInterface;
+import org.eclipse.basyx.vab.registry.memory.VABInMemoryRegistry;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
@@ -33,7 +42,7 @@
 public class TestGateway {
 	private BaSyxTCPServer<VABMapProvider> server;
 	private BaSyxTCPServer<DelegatingModelProvider> basyxGateway;
-	private AASHTTPServer httpGateway;
+	private BaSyxHTTPServer httpGateway;
 
 	@Before
 	public void build() { // Create VAB element
@@ -46,8 +55,8 @@
 		// Create ConnectorProviderMapper and add mapping from "basyx" to
 		// BaSyxConnectorProvider for gateway
 		ConnectorProviderMapper gatewayMapper = new ConnectorProviderMapper();
-		gatewayMapper.addConnectorProvider("basyx", new BaSyxConnectorProvider());
-		gatewayMapper.addConnectorProvider("http", new HTTPConnectorProvider());
+		gatewayMapper.addConnectorProvider("basyx", new BaSyxConnectorFactory());
+		gatewayMapper.addConnectorProvider("http", new HTTPConnectorFactory());
 
 		// Create tcp gateway using DelegatingModelProvider
 		basyxGateway = new BaSyxTCPServer<>(new DelegatingModelProvider(gatewayMapper), 6999);
@@ -56,7 +65,7 @@
 		DelegatingModelProvider httpGWProvider = new DelegatingModelProvider(gatewayMapper);
 		BaSyxContext context = new BaSyxContext("", "", "localhost", 5123);
 		context.addServletMapping("/path/to/gateway/*", new VABHTTPInterface<DelegatingModelProvider>(httpGWProvider));
-		httpGateway = new AASHTTPServer(context);
+		httpGateway = new BaSyxHTTPServer(context);
 
 		// Start element provider and gateway
 		server.start();
@@ -89,12 +98,12 @@
 	public void test() throws UnknownHostException, IOException {
 		// Create Directory, here it is configured statically, of course a dynamic
 		// request to e.g. a servlet is also possible
-		InMemoryDirectory directory = new InMemoryDirectory();
+		VABInMemoryRegistry directory = new VABInMemoryRegistry();
 		directory.addMapping("Elem", "http://localhost:5123/path/to/gateway//basyx://127.0.0.1:6999//basyx://127.0.0.1:6998");
 
 		// Create ConnectionProviderMapper for client
 		ConnectorProviderMapper clientMapper = new ConnectorProviderMapper();
-		clientMapper.addConnectorProvider("http", new HTTPConnectorProvider());
+		clientMapper.addConnectorProvider("http", new HTTPConnectorFactory());
 
 		// Create VABConnectionManager
 		VABConnectionManager manager = new VABConnectionManager(directory, clientMapper);
@@ -103,7 +112,7 @@
 		VABElementProxy proxy = manager.connectToVABElement("Elem");
 
 		// Test if the value is retrieved correctly
-		assertEquals(10, proxy.getModelPropertyValue("propertyA"));
+		assertEquals(10, proxy.getValue("propertyA"));
 	}
 
 	@After
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/manager/VABConnectionManagerStub.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/manager/VABConnectionManagerStub.java
index 662dbf7..3af0ac5 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/manager/VABConnectionManagerStub.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/manager/VABConnectionManagerStub.java
@@ -1,9 +1,18 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.vab.manager;
 
 import org.eclipse.basyx.testsuite.regression.vab.gateway.ConnectorProviderStub;
-import org.eclipse.basyx.vab.directory.memory.InMemoryDirectory;
 import org.eclipse.basyx.vab.manager.VABConnectionManager;
 import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
+import org.eclipse.basyx.vab.registry.memory.VABInMemoryRegistry;
 
 /**
  * A VABConnectionManager stub which automatically creates the directory entries
@@ -16,7 +25,7 @@
 
 	public VABConnectionManagerStub() {
 		// Create Stub with default DirectoryStub/ConnectorProviderStub
-		super(new InMemoryDirectory(), new ConnectorProviderStub());
+		super(new VABInMemoryRegistry(), new ConnectorProviderStub());
 	}
 
 	/**
@@ -31,12 +40,12 @@
 		getDirectoryService().addMapping("", "");
 	}
 
-	private InMemoryDirectory getDirectoryService() {
-		return (InMemoryDirectory) directoryService;
+	private VABInMemoryRegistry getDirectoryService() {
+		return (VABInMemoryRegistry) directoryService;
 	}
 
 	private ConnectorProviderStub getConnectorProvider() {
-		return (ConnectorProviderStub) connectorProvider;
+		return (ConnectorProviderStub) connectorFactory;
 	}
 
 	/**
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/model/VABModelMapTest.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/model/VABModelMapTest.java
index 7361dd6..9a3dc55 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/model/VABModelMapTest.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/model/VABModelMapTest.java
@@ -1,6 +1,16 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.vab.model;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
 
 import java.util.HashMap;
 import java.util.Map;
@@ -47,11 +57,61 @@
 	public void testEquals() {
 		VABModelMap<Object> expected = new VABModelMap<>();
 		expected.put("a", "b");
+		expected.put("x", "y");
 
 		Map<String, Object> map = new HashMap<>();
 		map.put("a", "b");
+		map.put("x", "y");
 
 		assertEquals(expected, map);
+
+		map.put("a", "c");
+		assertNotEquals(expected, map);
+
+		map.remove("a");
+		assertNotEquals(expected, map);
+	}
+
+	@Test
+	public void testEqualsFirstEntryNull() {
+		VABModelMap<Object> expected = new VABModelMap<>();
+		expected.put("a", null);
+		expected.put("x", "b");
+
+		VABModelMap<Object> map = new VABModelMap<>();
+		map.put("a", null);
+		map.put("x", "c");
+
+		assertNotEquals(map, expected);
+	}
+
+	@Test
+	public void testEqualsFirstEntrySame() {
+		VABModelMap<Object> expected = new VABModelMap<>();
+		expected.put("a", "1");
+		expected.put("x", "b");
+
+		VABModelMap<Object> map = new VABModelMap<>();
+		map.put("a", "1");
+		map.put("x", "c");
+
+		assertNotEquals(map, expected);
+	}
+
+	@Test
+	public void testEqualsMapEntrySame() {
+		VABModelMap<Object> contained = new VABModelMap<>();
+		contained.put("hello", "world");
+
+		VABModelMap<Object> expected = new VABModelMap<>();
+		expected.put("a", contained);
+		expected.put("x", "b");
+
+		VABModelMap<Object> map = new VABModelMap<>();
+		map.put("a", contained);
+		map.put("x", "c");
+
+		assertNotEquals(map, expected);
 	}
 
 }
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/Exceptions.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/Exceptions.java
index de5e108..dba4bf8 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/Exceptions.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/Exceptions.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.vab.modelprovider;
 
 import static org.junit.Assert.assertEquals;
@@ -37,7 +46,7 @@
 
 		// Non-existing parent element
 		try {
-			connVABElement.getModelPropertyValue("unknown/x");
+			connVABElement.getValue("unknown/x");
 			fail();
 		} catch (ResourceNotFoundException e) {
 			Result result = new Result(e);
@@ -58,7 +67,7 @@
 
 		// Invoke unsupported functional interface
 		try {
-			connVABElement.invokeOperation("operations/supplier");
+			connVABElement.invokeOperation("operations/supplier/invoke");
 			fail();
 		} catch (MalformedRequestException e) {
 			// this is for FileSystemProvider that does not support invoke
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/IModelProviderStub.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/IModelProviderStub.java
index 4de662d..7abe93a 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/IModelProviderStub.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/IModelProviderStub.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.vab.modelprovider;
 
 import org.eclipse.basyx.vab.exception.provider.ProviderException;
@@ -9,14 +18,14 @@
 	private Object value;
 
 	@Override
-	public Object getModelPropertyValue(String path) {
+	public Object getValue(String path) {
 		value = null;
 		this.path = path;
 		return null;
 	}
 
 	@Override
-	public void setModelPropertyValue(String path, Object newValue) throws ProviderException {
+	public void setValue(String path, Object newValue) throws ProviderException {
 		value = newValue;
 		this.path = path;
 	}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/MapCreateDelete.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/MapCreateDelete.java
index ac3f71c..ee88b4d 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/MapCreateDelete.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/MapCreateDelete.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.vab.modelprovider;
 
 import static org.junit.Assert.assertEquals;
@@ -33,12 +42,12 @@
 	private static void testCreateElements(VABElementProxy connVABElement) {
 		// Create property directly in root element
 		connVABElement.createValue("inRoot", 1.2);
-		Object toTest = connVABElement.getModelPropertyValue("inRoot");
+		Object toTest = connVABElement.getValue("inRoot");
 		assertEquals(1.2, toTest);
 		
 		// Create element in Map (with new key contained in the path)
 		connVABElement.createValue("/structure/map/inMap", "34");
-		toTest = connVABElement.getModelPropertyValue("/structure/map/inMap");
+		toTest = connVABElement.getValue("/structure/map/inMap");
 		assertEquals("34", toTest);
 		
 		// Create map element
@@ -46,7 +55,7 @@
 		newMap.put("entryA", 3);
 		newMap.put("entryB", 4);
 		connVABElement.createValue("mapInRoot", newMap);
-		toTest = connVABElement.getModelPropertyValue("mapInRoot");
+		toTest = connVABElement.getValue("mapInRoot");
 		assertTrue(toTest instanceof Map<?, ?>);
 		assertEquals(2, ((Map<String, Object>) toTest).size());
 		assertEquals(3, ((Map<String, Object>) toTest).get("entryA"));
@@ -59,14 +68,14 @@
 			// If inRoot would have been a list 0 could be added here
 			// => 1.2 has an "invalid" type for creating values in it
 		}
-		toTest = connVABElement.getModelPropertyValue("inRoot");
+		toTest = connVABElement.getValue("inRoot");
 		assertEquals(1.2, toTest);
 		
 		// Check case-sensitivity
 		connVABElement.createValue("inroot", 78);
-		toTest = connVABElement.getModelPropertyValue("inRoot");
+		toTest = connVABElement.getValue("inRoot");
 		assertEquals(1.2, toTest);
-		toTest = connVABElement.getModelPropertyValue("inroot");
+		toTest = connVABElement.getValue("inroot");
 		assertEquals(78, toTest);
 		
 		// Non-existing parent element
@@ -75,7 +84,7 @@
 			fail();
 		} catch (ResourceNotFoundException e) {}
 		try {
-			connVABElement.getModelPropertyValue("unknown/x");
+			connVABElement.getValue("unknown/x");
 			fail();
 		} catch (ResourceNotFoundException e) {}
 		
@@ -100,24 +109,24 @@
 			fail();
 		} catch (MalformedRequestException e) {
 		}
-		Object toTest = connVABElement.getModelPropertyValue("inRoot");
+		Object toTest = connVABElement.getValue("inRoot");
 		assertEquals(1.2, toTest);
 		
 		// - by index
 		connVABElement.deleteValue("inRoot");
 		try {
 			// "inRoot" should not exist anymore
-			connVABElement.getModelPropertyValue("inRoot");
+			connVABElement.getValue("inRoot");
 			fail();
 		} catch (ResourceNotFoundException e) {}
 		
 		// Check case-sensitivity
-		toTest = connVABElement.getModelPropertyValue("inroot");
+		toTest = connVABElement.getValue("inroot");
 		assertEquals(78, toTest);
 		connVABElement.deleteValue("inroot");
 		try {
 			// "inroot" should not exist anymore
-			connVABElement.getModelPropertyValue("inroot");
+			connVABElement.getValue("inroot");
 			fail();
 		} catch (ResourceNotFoundException e) {}
 		
@@ -129,18 +138,18 @@
 		} catch (MalformedRequestException e) {
 		}
 		
-		toTest = connVABElement.getModelPropertyValue("/structure/map/inMap");
+		toTest = connVABElement.getValue("/structure/map/inMap");
 		assertEquals("34", toTest);
 		// - by index
 		connVABElement.deleteValue("/structure/map/inMap");
-		toTest = connVABElement.getModelPropertyValue("/structure/map");
+		toTest = connVABElement.getValue("/structure/map");
 		assertEquals(0, ((Map<?, ?>) toTest).size());
 		
 		// Delete remaining complete Map
 		connVABElement.deleteValue("mapInRoot");
 		try {
 			// "mapInRoot" should not exist anymore
-			connVABElement.getModelPropertyValue("mapInRoot");
+			connVABElement.getValue("mapInRoot");
 			fail();
 		} catch (ResourceNotFoundException e) {}
 		
@@ -153,7 +162,7 @@
 			// It would be possible to delete "" from a "root list"
 			// => invalid type
 		}
-		toTest = connVABElement.getModelPropertyValue("/primitives/integer");
+		toTest = connVABElement.getValue("/primitives/integer");
 		assertEquals(123, toTest);
 		
 		// Null path - should throw exception
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/MapInvoke.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/MapInvoke.java
index df62326..a84f32f 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/MapInvoke.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/MapInvoke.java
@@ -1,8 +1,18 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.vab.modelprovider;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.fail;
 
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation;
 import org.eclipse.basyx.vab.exception.provider.MalformedRequestException;
 import org.eclipse.basyx.vab.exception.provider.ProviderException;
 import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
@@ -22,30 +32,30 @@
 		VABElementProxy connVABElement = connManager.connectToVABElement("urn:fhg:es.iese:vab:1:1:simplevabelement");
 	
 		// Invoke complex function
-		Object complex = connVABElement.invokeOperation("operations/complex", 12, 34);
+		Object complex = connVABElement.invokeOperation("operations/complex/", 12, 34);
 		assertEquals(46, complex);
 	
 		// Invoke unsupported functional interface
 		try {
-			connVABElement.invokeOperation("operations/supplier");
+			connVABElement.invokeOperation("operations/supplier/" + Operation.INVOKE);
 			fail();
 		} catch (ProviderException e) {}
 	
 		// Invoke non-existing operation
 		try {
-			connVABElement.invokeOperation("operations/unknown");
+			connVABElement.invokeOperation("operations/unknown/" + Operation.INVOKE);
 			fail();
 		} catch (ResourceNotFoundException e) {}
 	
 		// Invoke invalid operation -> not a function, but a primitive data type
 		try {
-			connVABElement.invokeOperation("operations/invalid");
+			connVABElement.invokeOperation("operations/invalid/" + Operation.INVOKE);
 			fail();
 		} catch (ProviderException e) {}
 	
 		// Invoke operations that throw Exceptions
 		try {
-			connVABElement.invokeOperation("operations/providerException");
+			connVABElement.invokeOperation("operations/providerException/" + Operation.INVOKE);
 			fail();
 		} catch (ProviderException e) {
 			// exception type not implemented, yet
@@ -53,7 +63,7 @@
 		}
 	
 		try {
-			connVABElement.invokeOperation("operations/nullException");
+			connVABElement.invokeOperation("operations/nullException/" + Operation.INVOKE);
 			fail();
 		} catch (ProviderException e) {
 			// exception type not implemented, yet
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/MapRead.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/MapRead.java
index 21eaa61..7523372 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/MapRead.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/MapRead.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.vab.modelprovider;
 
 import static org.junit.Assert.assertEquals;
@@ -26,66 +35,66 @@
 		VABElementProxy connVABElement = connManager.connectToVABElement("urn:fhg:es.iese:vab:1:1:simplevabelement");
 		
 		// Test path access
-		Object slashA = connVABElement.getModelPropertyValue("/primitives/integer");
-		Object slashB = connVABElement.getModelPropertyValue("primitives/integer/");
-		Object slashC = connVABElement.getModelPropertyValue("/primitives/integer/");
-		Object slashD = connVABElement.getModelPropertyValue("/primitives/integer/");
+		Object slashA = connVABElement.getValue("/primitives/integer");
+		Object slashB = connVABElement.getValue("primitives/integer/");
+		Object slashC = connVABElement.getValue("/primitives/integer/");
+		Object slashD = connVABElement.getValue("/primitives/integer/");
 		assertEquals(slashA, 123);
 		assertEquals(slashB, 123);
 		assertEquals(slashC, 123);
 		assertEquals(slashD, 123);
 		
 		// Test reading different data types
-		Object map = connVABElement.getModelPropertyValue("primitives");
-		Object doubleValue = connVABElement.getModelPropertyValue("primitives/double");
-		Object string = connVABElement.getModelPropertyValue("primitives/string");
+		Object map = connVABElement.getValue("primitives");
+		Object doubleValue = connVABElement.getValue("primitives/double");
+		Object string = connVABElement.getValue("primitives/string");
 		assertEquals(3, ((Map<?, ?>) map).size());
 		assertEquals(3.14d, doubleValue);
 		assertEquals("TestValue", string);
 		
 		// Test case sensitivity
-		Object caseSensitiveA = connVABElement.getModelPropertyValue("special/casesensitivity");
-		Object caseSensitiveB = connVABElement.getModelPropertyValue("special/caseSensitivity");
+		Object caseSensitiveA = connVABElement.getValue("special/casesensitivity");
+		Object caseSensitiveB = connVABElement.getValue("special/caseSensitivity");
 		assertEquals(true, caseSensitiveA);
 		assertEquals(false, caseSensitiveB);
 		
 		// Test reading null value
-		Object nullValue = connVABElement.getModelPropertyValue("special/null");
+		Object nullValue = connVABElement.getValue("special/null");
 		assertNull(nullValue);
 		
 		// Test reading serializable functions
-		Object serializableFunction = connVABElement.getModelPropertyValue("operations/serializable");
+		Object serializableFunction = connVABElement.getValue("operations/serializable");
 		Function<Object[], Object> testFunction = (Function<Object[], Object>) serializableFunction;
 		assertEquals(3, testFunction.apply(new Object[] { 1, 2 }));
 		
 		// Non-existing parent element
 		try {
-			connVABElement.getModelPropertyValue("unknown/x");
+			connVABElement.getValue("unknown/x");
 			fail();
 		} catch (ResourceNotFoundException e) {}
 		
 		// Non-existing target element
 		try {
-			connVABElement.getModelPropertyValue("primitives/unkown");
+			connVABElement.getValue("primitives/unkown");
 			fail();
 		} catch (ResourceNotFoundException e) {}
 		try {
-			connVABElement.getModelPropertyValue("unkown");
+			connVABElement.getValue("unkown");
 			fail();
 		} catch (ResourceNotFoundException e) {}
 		
 		// Nested access
-		assertEquals(100, connVABElement.getModelPropertyValue("special/nested/nested/value"));
+		assertEquals(100, connVABElement.getValue("special/nested/nested/value"));
 		
 		// Empty path
-		Object rootValueA = connVABElement.getModelPropertyValue("");
-		Object rootValueB = connVABElement.getModelPropertyValue("/");
+		Object rootValueA = connVABElement.getValue("");
+		Object rootValueB = connVABElement.getValue("/");
 		assertEquals(4, ((Map<?, ?>) rootValueA).size());
 		assertEquals(4, ((Map<?, ?>) rootValueB).size());
 		
 		// Null path - should throw exception
 		try {
-			connVABElement.getModelPropertyValue(null);
+			connVABElement.getValue(null);
 			fail();
 		} catch (MalformedRequestException e) {}
 	}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/MapUpdate.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/MapUpdate.java
index 8a8631e..b3b36df 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/MapUpdate.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/MapUpdate.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.vab.modelprovider;
 
 import static org.junit.Assert.assertEquals;
@@ -27,13 +36,13 @@
 		VABElementProxy connVABElement = connManager.connectToVABElement("urn:fhg:es.iese:vab:1:1:simplevabelement");
 		
 		// Set primitives
-		connVABElement.setModelPropertyValue("primitives/integer", 12);
-		connVABElement.setModelPropertyValue("primitives/double", 1.2d);
-		connVABElement.setModelPropertyValue("primitives/string", "updated");
+		connVABElement.setValue("primitives/integer", 12);
+		connVABElement.setValue("primitives/double", 1.2d);
+		connVABElement.setValue("primitives/string", "updated");
 		// Read back
-		Object integer = connVABElement.getModelPropertyValue("primitives/integer");
-		Object doubleValue = connVABElement.getModelPropertyValue("primitives/double");
-		Object string = connVABElement.getModelPropertyValue("primitives/string");
+		Object integer = connVABElement.getValue("primitives/integer");
+		Object doubleValue = connVABElement.getValue("primitives/double");
+		Object string = connVABElement.getValue("primitives/string");
 		// Test
 		assertTrue(integer instanceof Integer);
 		assertEquals(12, integer);
@@ -42,22 +51,22 @@
 		assertTrue(string instanceof String);
 		assertEquals("updated", string);
 		// Revert
-		connVABElement.setModelPropertyValue("primitives/integer", 123);
-		connVABElement.setModelPropertyValue("primitives/double", 3.14d);
-		connVABElement.setModelPropertyValue("primitives/string", "TestValue");
+		connVABElement.setValue("primitives/integer", 123);
+		connVABElement.setValue("primitives/double", 3.14d);
+		connVABElement.setValue("primitives/string", "TestValue");
 		
 		// Update serializable function
-		connVABElement.setModelPropertyValue("operations/serializable",
+		connVABElement.setValue("operations/serializable",
 				(Function<Object[], Object> & Serializable) (param) -> {
 					return (int) param[0] - (int) param[1];
 				});
 		// Read back
-		Object serializableFunction = connVABElement.getModelPropertyValue("operations/serializable");
+		Object serializableFunction = connVABElement.getValue("operations/serializable");
 		// Test
 		Function<Object[], Object> testFunction = (Function<Object[], Object>) serializableFunction;
 		assertEquals(-1, testFunction.apply(new Object[] { 2, 3 }));
 		// Revert
-		connVABElement.setModelPropertyValue("operations/serializable",
+		connVABElement.setValue("operations/serializable",
 				(Function<Object[], Object> & Serializable) (param) -> {
 					return (int) param[0] + (int) param[1];
 				});
@@ -68,28 +77,28 @@
 			fail();
 		} catch (ResourceNotFoundException e) {}
 		try {
-			connVABElement.getModelPropertyValue("unknown/newElement");
+			connVABElement.getValue("unknown/newElement");
 			fail();
 		} catch (ResourceNotFoundException e) {}
 		
 		// Test updating a non-existing element
 		try {
-			connVABElement.setModelPropertyValue("newElement", 10);
+			connVABElement.setValue("newElement", 10);
 			fail();
 		} catch (ResourceNotFoundException e) {}
 		try {
-			connVABElement.getModelPropertyValue("newElement");
+			connVABElement.getValue("newElement");
 			fail();
 		} catch (ResourceNotFoundException e) {}
 		
 		// Test updating an existing null-element
-		connVABElement.setModelPropertyValue("special/null", true);
-		Object bool = connVABElement.getModelPropertyValue("special/null");
+		connVABElement.setValue("special/null", true);
+		Object bool = connVABElement.getValue("special/null");
 		assertTrue((boolean) bool);
 
 		// Null path - should throw exception
 		try {
-			connVABElement.setModelPropertyValue(null, "");
+			connVABElement.setValue(null, "");
 			fail();
 		} catch (MalformedRequestException e) {}
 	}
@@ -104,7 +113,7 @@
 		newMap.put("testKey", "testValue");
 		// - push
 		try {
-			connVABElement.setModelPropertyValue(null, newMap);
+			connVABElement.setValue(null, newMap);
 			fail();
 		} catch (MalformedRequestException e) {}
 	
@@ -113,15 +122,15 @@
 		HashMap<String, Object> newMap2 = new HashMap<>();
 		newMap2.put("testKey2", "testValue2");
 		// - push
-		connVABElement.setModelPropertyValue("", newMap2);
+		connVABElement.setValue("", newMap2);
 		// - test
-		assertEquals("testValue2", connVABElement.getModelPropertyValue("testKey2"));
+		assertEquals("testValue2", connVABElement.getValue("testKey2"));
 		try {
-			connVABElement.getModelPropertyValue("testKey");
+			connVABElement.getValue("testKey");
 			fail();
 		} catch (ResourceNotFoundException e) {}
 		try {
-			connVABElement.getModelPropertyValue("primitives/integer");
+			connVABElement.getValue("primitives/integer");
 			fail();
 		} catch (ResourceNotFoundException e) {}
 	}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/SimpleVABElement.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/SimpleVABElement.java
index 98a5299..8087a69 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/SimpleVABElement.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/SimpleVABElement.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.vab.modelprovider;
 
 import java.io.Serializable;
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/TestCollectionProperty.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/TestCollectionProperty.java
index 7d304db..eb44011 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/TestCollectionProperty.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/TestCollectionProperty.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.vab.modelprovider;
 
 import static org.junit.Assert.assertEquals;
@@ -31,7 +40,7 @@
 		connVABElement.createValue("/structure/list/", 12);
 	
 		// Test reading whole lists
-		Collection<Object> collection = (Collection<Object>) connVABElement.getModelPropertyValue("/structure/list/");
+		Collection<Object> collection = (Collection<Object>) connVABElement.getValue("/structure/list/");
 		Iterator<Object> iterator = collection.iterator();
 		assertEquals(5, iterator.next());
 		assertEquals(12, iterator.next());
@@ -39,7 +48,7 @@
 
 		// Test invalid list access - single list elements cannot be accessed directly
 		try {
-			connVABElement.getModelPropertyValue("/structure/list/0");
+			connVABElement.getValue("/structure/list/0");
 			fail();
 		} catch (ResourceNotFoundException e) {}
 	
@@ -54,17 +63,17 @@
 		VABElementProxy connVABElement = connManager.connectToVABElement("urn:fhg:es.iese:vab:1:1:simplevabelement");
 	
 		// Read original collection
-		Collection<Object> original = (Collection<Object>) connVABElement.getModelPropertyValue("/structure/list/");
+		Collection<Object> original = (Collection<Object>) connVABElement.getValue("/structure/list/");
 	
 		// Replace complete value of the collection property
 		Collection<Object> replacement = new ArrayList<>();
 		replacement.add(100);
 		replacement.add(200);
 		replacement.add(300);
-		connVABElement.setModelPropertyValue("/structure/list/", replacement);
+		connVABElement.setValue("/structure/list/", replacement);
 	
 		// Read values back
-		Collection<Object> collection = (Collection<Object>) connVABElement.getModelPropertyValue("/structure/list/");
+		Collection<Object> collection = (Collection<Object>) connVABElement.getValue("/structure/list/");
 	
 		// Check test case results
 		assertEquals(3, collection.size());
@@ -72,13 +81,13 @@
 
 		// Test invalid list access - single list elements cannot be accessed directly
 		try {
-			connVABElement.setModelPropertyValue("/structure/list/0", 3);
+			connVABElement.setValue("/structure/list/0", 3);
 			fail();
 		} catch (ResourceNotFoundException e) {
 		}
 	
 		// Write original back
-		connVABElement.setModelPropertyValue("/structure/list/", original);
+		connVABElement.setValue("/structure/list/", original);
 	}
 
 	public static void testCreateDelete(VABConnectionManager connManager) {
@@ -87,7 +96,7 @@
 	
 		// Create element in Set (no key provided)
 		connVABElement.createValue("/structure/set/", true);
-		Object toTest = connVABElement.getModelPropertyValue("/structure/set/");
+		Object toTest = connVABElement.getValue("/structure/set/");
 		assertTrue(((Collection<?>) toTest).contains(true));
 	
 		// Delete at Set
@@ -96,28 +105,28 @@
 			connVABElement.deleteValue("/structure/set/0/");
 			fail();
 		} catch (ResourceNotFoundException e) {}
-		toTest = connVABElement.getModelPropertyValue("/structure/set/");
+		toTest = connVABElement.getValue("/structure/set/");
 		assertEquals(1, ((Collection<?>) toTest).size());
 		// - by object
 		connVABElement.deleteValue("/structure/set/", true);
-		toTest = connVABElement.getModelPropertyValue("/structure/set/");
+		toTest = connVABElement.getValue("/structure/set/");
 		assertEquals(0, ((Collection<?>) toTest).size());
 	
 		// Create elements in List (no key provided)
 		connVABElement.createValue("/structure/list/", 56);
-		toTest = connVABElement.getModelPropertyValue("/structure/list/");
+		toTest = connVABElement.getValue("/structure/list/");
 		assertTrue(((List<?>) toTest).contains(56));
 	
 		// Delete at List
 		// by object
 		connVABElement.deleteValue("/structure/list/", 56);
-		toTest = connVABElement.getModelPropertyValue("/structure/list/");
+		toTest = connVABElement.getValue("/structure/list/");
 		assertEquals(0, ((List<?>) toTest).size());
 	
 		// Create a list element
 		connVABElement.createValue("listInRoot", Arrays.asList(1, 1, 2, 3, 5));
 		// Test whole list
-		toTest = connVABElement.getModelPropertyValue("listInRoot");
+		toTest = connVABElement.getValue("listInRoot");
 		assertTrue(toTest instanceof List);
 		assertEquals(5, ((List<?>) toTest).size());
 		assertEquals(2, ((List<?>) toTest).get(2));
@@ -125,7 +134,7 @@
 		// Delete whole list
 		connVABElement.deleteValue("listInRoot");
 		try {
-			connVABElement.getModelPropertyValue("listInRoot");
+			connVABElement.getValue("listInRoot");
 			fail();
 		} catch (ResourceNotFoundException e) {}
 	
@@ -142,19 +151,19 @@
 			fail();
 		} catch (ResourceNotFoundException e) {}
 	
-		toTest = connVABElement.getModelPropertyValue("/structure/list/");
+		toTest = connVABElement.getValue("/structure/list/");
 		assertEquals(4, ((List<?>) toTest).size());
 	
 		// Delete half of the elements
 		connVABElement.deleteValue("/structure/list/", 10);
 		connVABElement.deleteValue("/structure/list/", 40);
-		toTest = connVABElement.getModelPropertyValue("/structure/list/");
+		toTest = connVABElement.getValue("/structure/list/");
 		assertEquals(2, ((List<?>) toTest).size());
 
 		// Delete remaining elements
 		connVABElement.deleteValue("/structure/list/", 20);
 		connVABElement.deleteValue("/structure/list/", 80);
-		toTest = connVABElement.getModelPropertyValue("/structure/list/");
+		toTest = connVABElement.getValue("/structure/list/");
 		assertEquals(0, ((List<?>) toTest).size());
 	}
 }
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/TestProvider.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/TestProvider.java
index dc916cd..071ee1f 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/TestProvider.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/TestProvider.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.vab.modelprovider;
 
 import org.eclipse.basyx.vab.manager.VABConnectionManager;
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/VABElementProxyTest.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/VABElementProxyTest.java
index c1eeee9..4c4dd26 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/VABElementProxyTest.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/VABElementProxyTest.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.vab.modelprovider;
 
 import static org.junit.Assert.assertEquals;
@@ -36,6 +45,6 @@
 		// Connect to element <i>a/b</i>
 		VABElementProxy bProxy = proxy.getDeepProxy("a/b");
 
-		assertEquals(0, bProxy.getModelPropertyValue("c"));
+		assertEquals(0, bProxy.getValue("c"));
 	}
 }
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/VABPathToolsTest.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/VABPathToolsTest.java
index 79efe0d..33d2842 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/VABPathToolsTest.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/VABPathToolsTest.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.vab.modelprovider;
 
 import static org.junit.Assert.assertArrayEquals;
@@ -169,15 +178,63 @@
 
 	@Test
 	public void testIsOperationPath() {
-		String[] positive = { "operations", "operations/", "/operations", "operations/", "operations/test/",
-				"operations/test", "/operations/test", "operations/test/" };
-		String[] negative = { "", "/operationX/", "/myOperation/", "/operationsFake/", "/operationsFake/operationX/" };
+		String[] positive = { "submodelElements/id/invoke", "submodelElements/id/invoke/",
+				"operations/id/invoke", "operations/id/invoke/", "operations/test", "elem/operations/id" };
+		String[] negative = { "", "/submodelElementsX/", "/myoperations/", "/submodelElementsFake/",
+				"/submodelElementsFake/operationX/", "submodelElements/id/" };
 		for (String test : positive) {
-			assertTrue(test, VABPathTools.isOperationPath(test));
+			assertTrue(test, VABPathTools.isOperationInvokationPath(test));
 		}
 		for (String test : negative) {
-			assertFalse(test, VABPathTools.isOperationPath(test));
+			assertFalse(test, VABPathTools.isOperationInvokationPath(test));
 		}
-		assertFalse(VABPathTools.isOperationPath(null));
+		assertFalse(VABPathTools.isOperationInvokationPath(null));
 	}
-}
\ No newline at end of file
+	
+	@Test
+	public void testStripInvokeFromPath() {
+		assertEquals("id", VABPathTools.stripInvokeFromPath("id/invoke"));
+		assertEquals("", VABPathTools.stripInvokeFromPath("invoke"));
+		assertEquals("", VABPathTools.stripInvokeFromPath("/invoke"));
+		assertEquals("id/value", VABPathTools.stripInvokeFromPath("id/value"));
+		assertEquals("", VABPathTools.stripInvokeFromPath(""));
+	}
+	
+	@Test
+	public void testGetPathFromURL() {
+		
+		String[] urls = {"http://localhost:8080/test/elem.aasx", "http://localhost/test/elem.aasx",
+				"basyx://127.0.0.1:4000//http://localhost:8080/test/elem.aasx", "/test/elem.aasx", "test/elem.aasx"};
+		
+		for(String url: urls) {
+			assertEquals("/test/elem.aasx", VABPathTools.getPathFromURL(url));
+		}
+	}
+
+	@Test
+	public void testHarmonizePathWithSuffix() {
+		String expected = "http://localhost:8080/server/subserver/suffix";
+		String[] toTest = { expected, 
+							"http://localhost:8080/server/subserver/suffix/", 
+							"http://localhost:8080/server/subserver/", 
+				"http://localhost:8080/server/subserver", };
+
+		for (String t : toTest) {
+			String harmonized = VABPathTools.harmonizePathWithSuffix(t, "suffix");
+			assertEquals(expected, harmonized);
+
+			// Check also for suffixes with a leading slash
+			String harmonizedLeadingSlash = VABPathTools.harmonizePathWithSuffix(t, "/suffix");
+			assertEquals(expected, harmonizedLeadingSlash);
+
+			// Check also for suffixes with a ending slash
+			String harmonizedEndingSlash = VABPathTools.harmonizePathWithSuffix(t, "suffix/");
+			assertEquals(expected, harmonizedEndingSlash);
+		}
+
+		// Check for edge case where a path is ending with the suffix, but not on its
+		// own
+		String edgeCaseExpected = "http://localhost:8080/server/subserversuffix/suffix";
+		assertEquals(edgeCaseExpected, VABPathTools.harmonizePathWithSuffix("http://localhost:8080/server/subserversuffix/", "suffix"));
+	}
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/filesystem/TestFileSystemProvider.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/filesystem/TestFileSystemProvider.java
index 8ada71c..bf72095 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/filesystem/TestFileSystemProvider.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/filesystem/TestFileSystemProvider.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.vab.modelprovider.filesystem;
 
 import org.eclipse.basyx.testsuite.regression.vab.modelprovider.SimpleVABElement;
@@ -8,7 +17,7 @@
 import org.eclipse.basyx.vab.modelprovider.filesystem.FileSystemProvider;
 import org.eclipse.basyx.vab.modelprovider.filesystem.filesystem.FileSystem;
 import org.eclipse.basyx.vab.modelprovider.filesystem.filesystem.GenericFileSystem;
-import org.eclipse.basyx.vab.protocol.api.ConnectorProvider;
+import org.eclipse.basyx.vab.protocol.api.ConnectorFactory;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -28,7 +37,7 @@
 	@Override
 	protected VABConnectionManager getConnectionManager() {
 		if (connManager == null) {
-			connManager = new VABConnectionManager(new TestsuiteDirectory(), new ConnectorProvider() {
+			connManager = new VABConnectionManager(new TestsuiteDirectory(), new ConnectorFactory() {
 				@Override
 				protected IModelProvider createProvider(String addr) {
 
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/lambda/TestLambdaProvider.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/lambda/TestLambdaProvider.java
index 207fb81..846b0c6 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/lambda/TestLambdaProvider.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/lambda/TestLambdaProvider.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.vab.modelprovider.lambda;
 
 import java.util.ArrayList;
@@ -15,7 +24,7 @@
 import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
 import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaProvider;
 import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaProviderHelper;
-import org.eclipse.basyx.vab.protocol.api.ConnectorProvider;
+import org.eclipse.basyx.vab.protocol.api.ConnectorFactory;
 
 /**
  * Tests the functionality of the VABLambdaProvider according to the test cases
@@ -36,7 +45,7 @@
 	private static HashMap<String, Object> mapElement = (HashMap<String, Object>) structureElement.get("map");
 
 	protected VABConnectionManager connManager = new VABConnectionManager(new TestsuiteDirectory(),
-			new ConnectorProvider() {
+			new ConnectorFactory() {
 
 				@Override
 				protected IModelProvider createProvider(String addr) {
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/map/TestMapProvider.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/map/TestMapProvider.java
index 624a0ea..65210f6 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/map/TestMapProvider.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/map/TestMapProvider.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.vab.modelprovider.map;
 
 import org.eclipse.basyx.testsuite.regression.vab.modelprovider.SimpleVABElement;
@@ -6,7 +15,7 @@
 import org.eclipse.basyx.vab.manager.VABConnectionManager;
 import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
 import org.eclipse.basyx.vab.modelprovider.map.VABMapProvider;
-import org.eclipse.basyx.vab.protocol.api.ConnectorProvider;
+import org.eclipse.basyx.vab.protocol.api.ConnectorFactory;
 
 /**
  * Tests the functionality of the VABMapProvider according to the test cases in
@@ -21,7 +30,7 @@
 	@Override
 	protected VABConnectionManager getConnectionManager() {
 		if (connManager == null) {
-			connManager = new VABConnectionManager(new TestsuiteDirectory(), new ConnectorProvider() {
+			connManager = new VABConnectionManager(new TestsuiteDirectory(), new ConnectorFactory() {
 				@Override
 				protected IModelProvider createProvider(String addr) {
 
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/basyx/TestVABBaSyxTCP.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/basyx/TestVABBaSyxTCP.java
index fdfbd4a..1cac05a 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/basyx/TestVABBaSyxTCP.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/basyx/TestVABBaSyxTCP.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.vab.protocol.basyx;
 
 import static org.junit.Assert.assertFalse;
@@ -9,7 +18,7 @@
 import org.eclipse.basyx.vab.manager.VABConnectionManager;
 import org.eclipse.basyx.vab.modelprovider.map.VABMapProvider;
 import org.eclipse.basyx.vab.protocol.basyx.connector.BaSyxConnector;
-import org.eclipse.basyx.vab.protocol.basyx.connector.BaSyxConnectorProvider;
+import org.eclipse.basyx.vab.protocol.basyx.connector.BaSyxConnectorFactory;
 import org.eclipse.basyx.vab.protocol.basyx.server.VABBaSyxTCPInterface;
 import org.junit.Rule;
 import org.junit.Test;
@@ -22,7 +31,7 @@
  */
 public class TestVABBaSyxTCP extends TestProvider {
 	protected VABConnectionManager connManager = new VABConnectionManager(new TestsuiteDirectory_BaSyxNative(),
-			new BaSyxConnectorProvider());
+			new BaSyxConnectorFactory());
 
 	@Rule
 	public VABTCPServerResource res = new VABTCPServerResource(new VABMapProvider(new SimpleVABElement()));
@@ -42,7 +51,7 @@
 	public void testSuccessfulShutdown() throws InterruptedException {
 		BaSyxConnector connector = new BaSyxConnector("localhost", 6998);
 
-		connector.getModelPropertyValue("integer");
+		connector.getValue("integer");
 
 		// Wait until thread is closed on server
 		Thread.sleep(100);
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/basyx/TestsuiteDirectory_BaSyxNative.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/basyx/TestsuiteDirectory_BaSyxNative.java
index 2eb8d50..61776a2 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/basyx/TestsuiteDirectory_BaSyxNative.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/basyx/TestsuiteDirectory_BaSyxNative.java
@@ -1,6 +1,15 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.vab.protocol.basyx;
 
-import org.eclipse.basyx.vab.directory.memory.InMemoryDirectory;
+import org.eclipse.basyx.vab.registry.memory.VABInMemoryRegistry;
 
 
 
@@ -11,7 +20,7 @@
  * @author kuhn
  *
  */
-public class TestsuiteDirectory_BaSyxNative extends InMemoryDirectory {
+public class TestsuiteDirectory_BaSyxNative extends VABInMemoryRegistry {
 
 	
 	/**
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/basyx/VABTCPServerResource.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/basyx/VABTCPServerResource.java
index 8743bf6..1d04e72 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/basyx/VABTCPServerResource.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/basyx/VABTCPServerResource.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.vab.protocol.basyx;
 
 import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
@@ -32,4 +41,4 @@
 	protected void after() {
 		server.stop();
 	}
-}
\ No newline at end of file
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/http/AASHTTPServerResource.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/http/AASHTTPServerResource.java
index f8c451e..9f68f61 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/http/AASHTTPServerResource.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/http/AASHTTPServerResource.java
@@ -1,6 +1,15 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.vab.protocol.http;
 
-import org.eclipse.basyx.vab.protocol.http.server.AASHTTPServer;
+import org.eclipse.basyx.vab.protocol.http.server.BaSyxHTTPServer;
 import org.eclipse.basyx.vab.protocol.http.server.BaSyxContext;
 import org.junit.rules.ExternalResource;
 
@@ -11,7 +20,7 @@
  *
  */
 public class AASHTTPServerResource extends ExternalResource {
-	private AASHTTPServer server;
+	private BaSyxHTTPServer server;
 	private BaSyxContext context;
 
 	/**
@@ -26,7 +35,7 @@
 	 */
 	@Override
     protected void before() {
-    	server = new AASHTTPServer(context);
+    	server = new BaSyxHTTPServer(context);
 		server.start();
     }
 
@@ -37,4 +46,4 @@
     protected void after() {
 		server.shutdown();
     }
-}
\ No newline at end of file
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/http/SimpleVABElementServlet.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/http/SimpleVABElementServlet.java
index ff97a3d..4cda615 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/http/SimpleVABElementServlet.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/http/SimpleVABElementServlet.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.vab.protocol.http;
 
 import org.eclipse.basyx.testsuite.regression.vab.modelprovider.SimpleVABElement;
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/http/TestVABHTTP.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/http/TestVABHTTP.java
index 78772e2..37658c5 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/http/TestVABHTTP.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/http/TestVABHTTP.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.vab.protocol.http;
 
 import static org.junit.Assert.assertEquals;
@@ -16,7 +25,7 @@
 import org.eclipse.basyx.vab.manager.VABConnectionManager;
 import org.eclipse.basyx.vab.modelprovider.VABPathTools;
 import org.eclipse.basyx.vab.modelprovider.map.VABMapProvider;
-import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorFactory;
 import org.eclipse.basyx.vab.protocol.http.server.BaSyxContext;
 import org.eclipse.basyx.vab.protocol.http.server.VABHTTPInterface;
 import org.junit.Rule;
@@ -30,7 +39,7 @@
  */
 public class TestVABHTTP extends TestProvider {
 	protected VABConnectionManager connManager = new VABConnectionManager(new TestsuiteDirectory(),
-			new HTTPConnectorProvider());
+			new HTTPConnectorFactory());
 
 	private RecordingProvider recorder = new RecordingProvider(new VABMapProvider(new HashMap<>()));
 
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/http/TestsuiteDirectory.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/http/TestsuiteDirectory.java
index 4177a48..4ebc0d7 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/http/TestsuiteDirectory.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/http/TestsuiteDirectory.java
@@ -1,6 +1,15 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.vab.protocol.http;
 
-import org.eclipse.basyx.vab.directory.memory.InMemoryDirectory;
+import org.eclipse.basyx.vab.registry.memory.VABInMemoryRegistry;
 
 
 
@@ -11,16 +20,29 @@
  * @author kuhn
  *
  */
-public class TestsuiteDirectory extends InMemoryDirectory {
-
+public class TestsuiteDirectory extends VABInMemoryRegistry {
 	
 	/**
 	 * Constructor - load all directory entries
 	 */
 	public TestsuiteDirectory() {
-		// Define mappings
-		// - Asset administration shells
-		addMapping("urn:fhg:es.iese:vab:1:1:simplevabelement",  "http://localhost:8080/basys.sdk/Testsuite/SimpleVAB/");
-		addMapping("urn:fhg:es.iese:aas:1:1:submodel", "http://localhost:8080/basys.sdk/Testsuite/SimpleAASSubmodel/");
+		this("http");
+	}
+	
+	/**
+	 * Constructor - load all directory entries with link 
+	 * protocol defined in the parameter
+	 * @param protocol
+	 */
+	public TestsuiteDirectory(String protocol) {
+		defineMapping(protocol);
+	}
+	
+	/**
+	 * Define mapping of submodel and vab element
+	 */
+	private void defineMapping(String protocol) {
+		addMapping("urn:fhg:es.iese:vab:1:1:simplevabelement",  protocol + "://localhost:8080/basys.sdk/Testsuite/SimpleVAB/");
+		addMapping("urn:fhg:es.iese:aas:1:1:submodel", protocol + "://localhost:8080/basys.sdk/Testsuite/SimpleAASSubmodel/");
 	}
 }
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/https/DefaultHostNameVerifier.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/https/DefaultHostNameVerifier.java
new file mode 100644
index 0000000..7e0f876
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/https/DefaultHostNameVerifier.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.vab.protocol.https;
+
+
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.SSLSession;
+
+/**
+ * A default host name verifier which verifies every host name
+ * Used for testing with self signed certificate
+ * @author haque
+ *
+ */
+public class DefaultHostNameVerifier implements HostnameVerifier {
+    @Override
+    public boolean verify(String s, SSLSession sslSession) {
+        return true;
+    }
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/https/DefaultTrustManager.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/https/DefaultTrustManager.java
new file mode 100644
index 0000000..0cee46b
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/https/DefaultTrustManager.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.vab.protocol.https;
+
+import javax.net.ssl.X509TrustManager;
+import java.security.cert.X509Certificate;
+
+/**
+ * A Default Trust manager class which trusts everything
+ * Used for testing with self signed certificate
+ * @author haque
+ *
+ */
+public class DefaultTrustManager implements X509TrustManager {
+    @Override
+    public void checkClientTrusted(X509Certificate[] x509Certificates, String s) {
+    }
+
+    @Override
+    public void checkServerTrusted(X509Certificate[] x509Certificates, String s) {
+    }
+
+    @Override
+    public X509Certificate[] getAcceptedIssuers() {
+        return new X509Certificate[0];
+    }
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/https/HTTPSConnector.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/https/HTTPSConnector.java
new file mode 100644
index 0000000..0d6bd32
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/https/HTTPSConnector.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.vab.protocol.https;
+
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
+
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnector;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * An HTTPS Connector class which can be used
+ * for creating an HTTPS Client with self signed SSL certificate
+ * and communicating in REST 
+ * 
+ * @author haque
+ *
+ */
+public class HTTPSConnector extends HTTPConnector {
+	private static Logger logger = LoggerFactory.getLogger(HTTPSConnector.class);
+	
+	/**
+	 * Initiates an HTTPSConnector with given address
+	 * @param address
+	 */
+	public HTTPSConnector(String address) {
+		super(address);
+		setHttpsClient();
+	}
+	
+	/**
+	 * Initiates an HTTPSConnector with given address and media type
+	 * @param address
+	 * @param mediaType
+	 */
+	public HTTPSConnector(String address, String mediaType) { 
+		super(address, mediaType);
+		setHttpsClient();
+	}
+	
+	/**
+	 * Configures the client so that it can run with HTTPS protocol
+	 */
+	private void setHttpsClient() {
+		try {
+			this.client = JerseyHttpsClientFactory.getJerseyHTTPSClient();
+		} catch (KeyManagementException | NoSuchAlgorithmException e) {
+			logger.error("Cannot create a https client");
+		}
+	}
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/https/HTTPSConnectorProvider.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/https/HTTPSConnectorProvider.java
new file mode 100644
index 0000000..3d63679
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/https/HTTPSConnectorProvider.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.vab.protocol.https;
+
+import org.eclipse.basyx.vab.coder.json.connector.JSONConnector;
+import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
+import org.eclipse.basyx.vab.protocol.api.ConnectorFactory;
+
+/**
+ * An HTTPS Connector provider class
+ * which uses a HTTPSConnector in domain having self signed certificate
+ * @author haque
+ *
+ */
+public class HTTPSConnectorProvider extends ConnectorFactory {
+
+	/**
+	 * returns HTTPSConnetor wrapped with ConnectedHashmapProvider that handles
+	 * message header information
+	 */
+	@Override
+	protected IModelProvider createProvider(String addr) {
+		return new JSONConnector(new HTTPSConnector(addr));
+	}
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/https/JerseyHttpsClientFactory.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/https/JerseyHttpsClientFactory.java
new file mode 100644
index 0000000..6d68d2c
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/https/JerseyHttpsClientFactory.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.vab.protocol.https;
+
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
+import javax.ws.rs.client.Client;
+import javax.ws.rs.client.ClientBuilder;
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+
+/**
+ * A Factory class containing methods creating an HTTPS client
+ * with no verification and validation for self signed SSL
+ * and other helper methods
+ * 
+ * @author haque
+ *
+ */
+public class JerseyHttpsClientFactory {
+
+	/**
+	 * Returns an HTTPS client
+	 * @return
+	 * @throws KeyManagementException
+	 * @throws NoSuchAlgorithmException
+	 */
+    public static Client getJerseyHTTPSClient() throws KeyManagementException, NoSuchAlgorithmException {
+        SSLContext sslContext = getSslContext();
+        HostnameVerifier allHostsValid = new DefaultHostNameVerifier();
+
+        return ClientBuilder.newBuilder()
+                .sslContext(sslContext)
+                .hostnameVerifier(allHostsValid)
+                .build();
+    }
+
+    /**
+     * Retrieves an SSL Context
+     * with TLSv1 protocol
+     * @return
+     * @throws NoSuchAlgorithmException
+     * @throws KeyManagementException
+     */
+    private static SSLContext getSslContext() throws NoSuchAlgorithmException,
+                                                     KeyManagementException {
+        SSLContext sslContext = SSLContext.getInstance("TLSv1");
+
+        KeyManager[] keyManagers = null;
+        TrustManager[] trustManager = {new DefaultTrustManager()};
+        SecureRandom secureRandom = new SecureRandom();
+
+        sslContext.init(keyManagers, trustManager, secureRandom);
+
+        return sslContext;
+    }
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/https/TestVABHTTPS.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/https/TestVABHTTPS.java
new file mode 100644
index 0000000..a467dd4
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/https/TestVABHTTPS.java
@@ -0,0 +1,146 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.testsuite.regression.vab.protocol.https;
+
+import static org.junit.Assert.assertEquals;
+
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
+import java.util.HashMap;
+import java.util.List;
+
+import javax.ws.rs.client.Client;
+import javax.ws.rs.client.WebTarget;
+import javax.ws.rs.client.Invocation.Builder;
+import javax.ws.rs.core.MediaType;
+
+import org.eclipse.basyx.testsuite.regression.vab.modelprovider.TestProvider;
+import org.eclipse.basyx.testsuite.regression.vab.protocol.http.AASHTTPServerResource;
+import org.eclipse.basyx.testsuite.regression.vab.protocol.http.SimpleVABElementServlet;
+import org.eclipse.basyx.testsuite.regression.vab.protocol.http.TestVABHTTP;
+import org.eclipse.basyx.testsuite.regression.vab.protocol.http.TestsuiteDirectory;
+import org.eclipse.basyx.testsuite.regression.vab.support.RecordingProvider;
+import org.eclipse.basyx.vab.manager.VABConnectionManager;
+import org.eclipse.basyx.vab.modelprovider.VABPathTools;
+import org.eclipse.basyx.vab.modelprovider.map.VABMapProvider;
+import org.eclipse.basyx.vab.protocol.http.server.BaSyxContext;
+import org.eclipse.basyx.vab.protocol.http.server.VABHTTPInterface;
+import org.junit.Rule;
+import org.junit.Test;
+
+/**
+ * Test VAB using HTTPS protocol. This is an integration test
+ * 
+ * @author haque
+ *
+ */
+public class TestVABHTTPS extends TestProvider {
+	protected VABConnectionManager connManager = new VABConnectionManager(new TestsuiteDirectory("https"),
+			new HTTPSConnectorProvider());
+
+	private RecordingProvider recorder = new RecordingProvider(new VABMapProvider(new HashMap<>()));
+
+	/**
+	 * Makes sure Tomcat Server is started after before each test case
+	 */
+	@Rule
+	public AASHTTPServerResource res = new AASHTTPServerResource(
+			new BaSyxContext("/basys.sdk", 
+					System.getProperty("java.io.tmpdir"), "localhost", 8080, true, "resources/ssl.cert", "pass123")
+					.addServletMapping("/Testsuite/SimpleVAB/*", new SimpleVABElementServlet())
+					.addServletMapping("/Testsuite/Recorder/*", new VABHTTPInterface<RecordingProvider>(recorder)));
+
+	@Override
+	protected VABConnectionManager getConnectionManager() {
+		return connManager;
+	}
+	
+	/**
+	 * Tests for URL with no ending slash when accessing the root element, e.g.
+	 * http://localhost:8080/basys.sdk/Testsuite/SimpleVAB <br />
+	 * The SDK ensures that each access ends with a <i>/</i>. However, browser
+	 * requests do not necessarily conform to this
+	 * @throws NoSuchAlgorithmException 
+	 * @throws KeyManagementException 
+	 */
+	@Test
+	public void testRootURL() throws KeyManagementException, NoSuchAlgorithmException {
+		performRequest("https://localhost:8080/basys.sdk/Testsuite/SimpleVAB");
+	}
+
+	/**
+	 * Tests if multiple parameters are correctly accepted and passed to the
+	 * provider
+	 */
+	@Test
+	public void testParameters() {
+		recorder.reset();
+
+		String parameterRequest = "test?a=1,2&b=3,4";
+
+		performRequestNoException("https://localhost:8080/basys.sdk/Testsuite/Recorder/" + parameterRequest);
+
+		List<String> paths = recorder.getPaths();
+
+		assertEquals(1, paths.size());
+		assertEquals(parameterRequest, paths.get(0));
+	}
+
+	/**
+	 * Tests if having no parameter has no influence on the path
+	 */
+	@Test
+	public void testNoParameters() {
+		recorder.reset();
+
+		String parameterRequest = "test";
+
+		performRequestNoException("https://localhost:8080/basys.sdk/Testsuite/Recorder/" + parameterRequest);
+
+		List<String> paths = recorder.getPaths();
+
+		assertEquals(1, paths.size());
+		assertEquals(parameterRequest, VABPathTools.stripSlashes(paths.get(0)));
+	}
+
+	/**
+	 * Performs an HTTP request on an URL
+	 * 
+	 * @param URL
+	 * @throws NoSuchAlgorithmException 
+	 * @throws KeyManagementException 
+	 */
+	private void performRequest(String URL) throws KeyManagementException, NoSuchAlgorithmException {
+		Client client = JerseyHttpsClientFactory.getJerseyHTTPSClient();
+
+		// Called URL
+		WebTarget resource = client.target(URL);
+
+		// Build request, set JSON encoding
+		Builder request = resource.request();
+		request.accept(MediaType.APPLICATION_JSON);
+
+		// Perform request
+		request.get(String.class);
+	}
+
+	/**
+	 * Same as {@link TestVABHTTP#performRequest} but ignores exceptions
+	 * 
+	 * @param URL
+	 */
+	private void performRequestNoException(String URL) {
+		try {
+			performRequest(URL);
+		} catch (Exception e) {
+			// Does not matter
+		}
+	}
+}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/opcua/TestVABOpcUa.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/opcua/TestVABOpcUa.java
index f324bbe..fa50ad4 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/opcua/TestVABOpcUa.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/opcua/TestVABOpcUa.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.vab.protocol.opcua;
 
 import org.eclipse.basyx.vab.gateway.ConnectorProviderMapper;
@@ -45,10 +54,10 @@
         clientMapper.addConnectorProvider("opc.tcp", new OpcUaConnectorProvider());
         try {
             clientMapper.getConnector("opc.tcp://opcua.demo-this.com:51210/UA/SampleServer")
-                    .setModelPropertyValue("0:Objects/2:Data/2:Static/2:AnalogScalar/2:Int32Value", 42);
+                    .setValue("0:Objects/2:Data/2:Static/2:AnalogScalar/2:Int32Value", 42);
 
             Object ret = clientMapper.getConnector("opc.tcp://opcua.demo-this.com:51210/UA/SampleServer")
-                    .getModelPropertyValue("0:Objects/2:Data/2:Static/2:AnalogScalar/2:Int32Value");
+                    .getValue("0:Objects/2:Data/2:Static/2:AnalogScalar/2:Int32Value");
             Assert.assertEquals("42", ret);
         } catch (Exception e) {
             // TODO Auto-generated catch block
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/support/RecordingProvider.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/support/RecordingProvider.java
index 8b318e6..c59d731 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/support/RecordingProvider.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/support/RecordingProvider.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.vab.support;
 
 import java.util.ArrayList;
@@ -36,15 +45,15 @@
 
 
 	@Override
-	public Object getModelPropertyValue(String path) throws ProviderException {
+	public Object getValue(String path) throws ProviderException {
 		paths.add(path);
-		return wrapped.getModelPropertyValue(path);
+		return wrapped.getValue(path);
 	}
 
 	@Override
-	public void setModelPropertyValue(String path, Object newValue) throws ProviderException {
+	public void setValue(String path, Object newValue) throws ProviderException {
 		paths.add(path);
-		wrapped.setModelPropertyValue(path, newValue);
+		wrapped.setValue(path, newValue);
 	}
 
 	@Override
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/support/TestTypeDestroyer.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/support/TestTypeDestroyer.java
index e6c40b9..617fc77 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/support/TestTypeDestroyer.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/support/TestTypeDestroyer.java
@@ -1,9 +1,19 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
 package org.eclipse.basyx.testsuite.regression.vab.support;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
+import java.util.ArrayList;
 import java.util.Map;
 
 import org.eclipse.basyx.testsuite.regression.vab.modelprovider.SimpleVABElement;
@@ -17,12 +27,16 @@
  */
 public class TestTypeDestroyer {
 	
+	@SuppressWarnings("unchecked")
 	@Test
 	public void testTypeDestroyer() {
 		SimpleVABElement sm = new SimpleVABElement();
 		Map<String, Object> generic = TypeDestroyer.destroyType(sm);
 		assertTrue(sm instanceof SimpleVABElement);
 		assertFalse(generic instanceof SimpleVABElement);
+
+		// Replace set with list as transmission over VAB would do
+		((Map<String, Object>) sm.get("structure")).put("set", new ArrayList<>());
 		assertEquals(generic, sm);
 	}
 }
diff --git a/sdks/java/basys.sdk/src/test/resources/aas/factory/json/aasJsonSchemaV2.0.1_Example.json b/sdks/java/basys.sdk/src/test/resources/aas/factory/json/aasJsonSchemaV2.0.1_Example.json
new file mode 100644
index 0000000..afa70e0
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/resources/aas/factory/json/aasJsonSchemaV2.0.1_Example.json
@@ -0,0 +1,570 @@
+{
+  "assetAdministrationShells": [
+    {
+      "asset": {
+        "keys": [
+          {
+            "type": "Asset",
+            "local": true,
+            "value": "http://customer.com/assets/KHBVZJSQKIY",
+            "idType": "IRI"
+          }
+        ],
+        "kind": "Type",
+        "idShort": "assetId1",
+        "identification": {
+        	"idType": "IRI",
+        	"id": "assetId1"
+        }
+      },
+      "submodels": [
+        {
+          "keys": [
+            {
+              "type": "Submodel",
+              "local": true,
+              "value": "http.//i40.customer.com/type/1/1/7A7104BDAB57E184",
+              "idType": "IRI"
+            }
+          ],
+          "idShort": "submodelId1",
+	      "identification": {
+	      	  "idType": "IRI",
+	          "id": "submodelId1"
+	      }
+        },
+        {
+          "keys": [
+            {
+              "type": "Submodel",
+              "local": true,
+              "value": "http://i40.customer.com/instance/1/1/AC69B1CB44F07935",
+              "idType": "IRI"
+            }
+          ],
+          "idShort": "submodelId2",
+	      "identification": {
+	      	  "idType": "IRI",
+	          "id": "submodelId2"
+	      }
+        },
+        {
+          "keys": [
+            {
+              "type": "Submodel",
+              "local": true,
+              "value": "http://i40.customer.com/type/1/1/1A7B62B529F19152",
+              "idType": "IRI"
+            }
+          ],
+          "idShort": "submodelId3",
+	      "identification": {
+	      	  "idType": "IRI",
+	          "id": "submodelId3"
+	      }
+        }
+      ],
+      "conceptDictionaries": [],
+      "identification": {
+        "idType": "IRI",
+        "id": "http://customer.com/aas/9175_7013_7091_9168"
+      },
+      "idShort": "ExampleMotor",
+      "category": "CONSTANT",
+      "modelType": {
+        "name": "AssetAdministrationShell"
+      }
+    }
+  ],
+  "assets": [
+    {
+      "assetIdentificationModelRef": {
+        "keys": [
+          {
+            "type": "Submodel",
+            "local": true,
+            "value": "i40.customer.com/type/1/1/F13E8576F6488342",
+            "idType": "IRI"
+          }
+        ]
+      },
+      "identification": {
+        "idType": "IRI",
+        "id": "http://customer.com/assets/KHBVZJSQKIY"
+      },
+      "idShort": "ServoDCMotor",
+      "category": "",
+      "modelType": {
+        "name": "Asset"
+      },
+      "kind": "Instance"
+    }
+  ],
+  "submodels": [
+    {
+      "semanticId": {
+        "keys": [
+          {
+            "type": "GlobalReference",
+            "local": false,
+            "value": "0173-1#01-AFZ615#016",
+            "idType": "IRDI"
+          }
+        ]
+      },
+      "identification": {
+        "idType": "IRI",
+        "id": "http.//i40.customer.com/type/1/1/7A7104BDAB57E184"
+      },
+      "idShort": "TechnicalData",
+      "category": "CONSTANT",
+      "modelType": {
+        "name": "Submodel"
+      },
+      "kind": "Instance",
+      "submodelElements": [
+        {
+          "value": "5000",
+          "semanticId": {
+            "keys": [
+              {
+                "type": "ConceptDescription",
+                "local": true,
+                "value": "0173-1#02-BAA120#008",
+                "idType": "IRDI"
+              }
+            ]
+          },
+          "constraints": [],
+          "idShort": "MaxRotationSpeed",
+          "category": "PARAMETER",
+          "modelType": {
+            "name": "Property"
+          },
+          "valueType": "integer",
+          "kind": "Instance"
+        }
+      ]
+    },
+    {
+      "semanticId": {
+        "keys": []
+      },
+      "identification": {
+        "idType": "IRI",
+        "id": "http://i40.customer.com/type/1/1/1A7B62B529F19152"
+      },
+      "idShort": "Documentation",
+      "category": "CONSTANT",
+      "modelType": {
+        "name": "Submodel"
+      },
+      "kind": "Instance",
+      "submodelElements": [
+        {
+          "ordered": false,
+          "allowDuplicates": false,
+          "semanticId": {
+            "keys": [
+              {
+                "type": "ConceptDescription",
+                "local": true,
+                "value": "www.vdi2770.com/blatt1/Entwurf/Okt18/cd/Document",
+                "idType": "IRI"
+              }
+            ]
+          },
+          "constraints": [],
+          "idShort": "OperatingManual",
+          "category": "",
+          "modelType": {
+            "name": "SubmodelElementCollection"
+          },
+          "value": [
+            {
+              "value": "Operating Manual",
+              "semanticId": {
+                "keys": [
+                  {
+                    "type": "ConceptDescription",
+                    "local": true,
+                    "value": "www.vdi2770.com/blatt1/Entwurf/Okt18/cd/Description/Title",
+                    "idType": "IRI"
+                  }
+                ]
+              },
+              "constraints": [],
+              "idShort": "Title",
+              "modelType": {
+                "name": "Property"
+              },
+              "valueType": "langString",
+              "kind": "Instance"
+            },
+            {
+              "mimeType": "application/pdf",
+              "value": "/aasx/OperatingManual.pdf",
+              "semanticId": {
+                "keys": [
+                  {
+                    "type": "ConceptDescription",
+                    "local": true,
+                    "value": "www.vdi2770.com/blatt1/Entwurf/Okt18/cd/StoredDocumentRepresentation/DigitalFile",
+                    "idType": "IRI"
+                  }
+                ]
+              },
+              "constraints": [],
+              "idShort": "DigitalFile_PDF",
+              "category": "PARAMETER",
+              "modelType": {
+                "name": "File"
+              },
+              "kind": "Instance"
+            }
+          ],
+          "kind": "Instance"
+        }
+      ]
+    },
+    {
+      "semanticId": {
+        "keys": []
+      },
+      "qualifiers": [],
+      "identification": {
+        "idType": "IRI",
+        "id": "http://i40.customer.com/instance/1/1/AC69B1CB44F07935"
+      },
+      "idShort": "OperationalData",
+      "category": "VARIABLE",
+      "modelType": {
+        "name": "Submodel"
+      },
+      "kind": "Instance",
+      "submodelElements": [
+        {
+          "value": "4370",
+          "hasDataSpecification": {
+            "reference": []
+          },
+          "semanticId": {
+            "keys": [
+              {
+                "type": "ConceptDescription",
+                "local": true,
+                "value": "http://customer.com/cd/1/1/18EBD56F6B43D895",
+                "idType": "IRI"
+              }
+            ]
+          },
+          "constraints": [],
+          "idShort": "RotationSpeed",
+          "category": "VARIABLE",
+          "modelType": {
+            "name": "Property"
+          },
+          "valueType": "integer",
+          "kind": "Instance"
+        }
+      ]
+    }
+  ],
+  "conceptDescriptions": [
+    {
+      "identification": {
+        "idType": "IRI",
+        "id": "www.vdi2770.com/blatt1/Entwurf/Okt18/cd/Description/Title"
+      },
+      "idShort": "Title",
+      "category": "CONSTANT",
+      "modelType": {
+        "name": "ConceptDescription"
+      },
+      "embeddedDataSpecifications": [
+        {
+          "dataSpecification": {
+            "keys": [
+              {
+                "type": "GlobalReference",
+                "local": false,
+                "value": "http://admin-shell.io/DataSpecificationTemplates/DataSpecificationIEC61360",
+                "idType": "IRI"
+              }
+            ]
+          },
+          "dataSpecificationContent": {
+            "preferredName": [
+              {
+                "language": "EN",
+                "text": "Title"
+              },
+              {
+                "language": "DE",
+                "text": "Titel"
+              }
+            ],
+            "shortName": [
+              {
+                "language": "EN",
+                "text": "Title"
+              },
+              {
+                "language": "DE",
+                "text": "Titel"
+              }
+            ],
+            "unit": "",
+            "sourceOfDefinition": "",
+            "dataType": "STRING_TRANSLATABLE",
+            "definition": [
+              {
+                "language": "DE",
+                "text": "Sprachabhängiger Titel des Dokuments."
+              }
+            ]
+          }
+        }
+      ],
+      "isCaseOf": []
+    },
+    {
+      "identification": {
+        "idType": "IRI",
+        "id": "www.vdi2770.com/blatt1/Entwurf/Okt18/cd/StoredDocumentRepresentation/DigitalFile"
+      },
+      "idShort": "DigitalFile",
+      "modelType": {
+        "name": "ConceptDescription"
+      },
+      "embeddedDataSpecifications": [
+        {
+          "dataSpecification": {
+            "keys": [
+              {
+                "type": "GlobalReference",
+                "local": false,
+                "value": "http://admin-shell.io/DataSpecificationTemplates/DataSpecificationIEC61360",
+                "idType": "IRI"
+              }
+            ]
+          },
+          "dataSpecificationContent": {
+            "preferredName": [
+              {
+                "language": "EN",
+                "text": "Digital File"
+              },
+              {
+                "language": "DE",
+                "text": "Digitale Datei"
+              }
+            ],
+            "shortName": [
+              {
+                "language": "EN",
+                "text": "DigitalFile"
+              },
+              {
+                "language": "DE",
+                "text": "DigitaleDatei"
+              }
+            ],
+            "unit": "",
+            "sourceOfDefinition": "",
+            "dataType": "STRING",
+            "definition": [
+              {
+                "language": "DE",
+                "text": "Eine Datei, die die DocumentVersion repräsentiert. Neben der obligatorischen PDF/A Datei können weitere Dateien angegeben werden."
+              }
+            ]
+          }
+        }
+      ],
+      "isCaseOf": []
+    },
+    {
+      "identification": {
+        "idType": "IRDI",
+        "id": "0173-1#02-BAA120#008"
+      },
+      "administration": {
+        "version": "",
+        "revision": "2"
+      },
+      "idShort": "MaxRotationSpeed",
+      "category": "PROPERTY",
+      "modelType": {
+        "name": "ConceptDescription"
+      },
+      "embeddedDataSpecifications": [
+        {
+          "dataSpecification": {
+            "keys": []
+          },
+          "dataSpecificationContent": {
+            "preferredName": [
+              {
+                "language": "de",
+                "text": "max. Drehzahl"
+              },
+              {
+                "language": "en",
+                "text": "Max. rotation speed"
+              }
+            ],
+            "shortName": [],
+            "unit": "1/min",
+            "unitId": {
+              "keys": [
+                {
+                  "type": "GlobalReference",
+                  "local": false,
+                  "value": "0173-1#05-AAA650#002",
+                  "idType": "IRDI"
+                }
+              ]
+            },
+            "sourceOfDefinition": "",
+            "dataType": "REAL_MEASURE",
+            "definition": [
+              {
+                "language": "de",
+                "text": "Höchste zulässige Drehzahl, mit welcher der Motor oder die Speiseinheit betrieben werden darf"
+              },
+              {
+                "language": "en",
+                "text": "Greatest permissible rotation speed with which the motor or feeding unit may be operated"
+              }
+            ]
+          }
+        }
+      ],
+      "isCaseOf": [
+        {
+          "keys": []
+        }
+      ]
+    },
+    {
+      "identification": {
+        "idType": "IRI",
+        "id": "http://customer.com/cd/1/1/18EBD56F6B43D895"
+      },
+      "idShort": "RotationSpeed",
+      "category": "PROPERTY",
+      "modelType": {
+        "name": "ConceptDescription"
+      },
+      "embeddedDataSpecifications": [
+        {
+          "dataSpecification": {
+            "keys": [
+              {
+                "type": "GlobalReference",
+                "local": false,
+                "value": "http://admin-shell.io/DataSpecificationTemplates/DataSpecificationIEC61360",
+                "idType": "IRI"
+              }
+            ]
+          },
+          "dataSpecificationContent": {
+            "preferredName": [
+              {
+                "language": "DE",
+                "text": "Aktuelle Drehzahl"
+              },
+              {
+                "language": "EN",
+                "text": "Actual rotation speed"
+              }
+            ],
+            "shortName": [
+              {
+                "language": "DE",
+                "text": "AktuelleDrehzahl"
+              },
+              {
+                "language": "EN",
+                "text": "ActualRotationSpeed"
+              }
+            ],
+            "unit": "1/min",
+            "unitId": {
+              "keys": [
+                {
+                  "type": "GlobalReference",
+                  "local": false,
+                  "value": "0173-1#05-AAA650#002",
+                  "idType": "IRDI"
+                }
+              ]
+            },
+            "sourceOfDefinition": "",
+            "dataType": "REAL_MEASURE",
+            "definition": [
+              {
+                "language": "DE",
+                "text": "Aktuelle Drehzahl, mit welcher der Motor oder die Speiseinheit betrieben wird"
+              },
+              {
+                "language": "EN",
+                "text": "Actual rotation speed with which the motor or feeding unit is operated"
+              }
+            ]
+          }
+        }
+      ],
+      "isCaseOf": []
+    },
+    {
+      "identification": {
+        "idType": "IRI",
+        "id": "www.vdi2770.com/blatt1/Entwurf/Okt18/cd/Document"
+      },
+      "idShort": "Document",
+      "modelType": {
+        "name": "ConceptDescription"
+      },
+      "embeddedDataSpecifications": [
+        {
+          "dataSpecification": {
+            "keys": [
+              {
+                "type": "GlobalReference",
+                "local": false,
+                "value": "http://admin-shell.io/DataSpecificationTemplates/DataSpecificationIEC61360",
+                "idType": "IRI"
+              }
+            ]
+          },
+          "dataSpecificationContent": {
+            "preferredName": [],
+            "shortName": [
+              {
+                "language": "EN",
+                "text": "Document"
+              },
+              {
+                "language": "DE",
+                "text": "Dokument"
+              }
+            ],
+            "unit": "",
+            "sourceOfDefinition": "[ISO 15519-1:2010]",
+            "dataType": "STRING",
+            "definition": [
+              {
+                "language": "DE",
+                "text": "Feste und geordnete Menge von für die Verwendung durch Personen bestimmte Informationen, die verwaltet und als Einheit zwischen Benutzern und System ausgetauscht werden kann."
+              }
+            ]
+          }
+        }
+      ],
+      "isCaseOf": [],
+      "descriptions": []
+    }
+  ]
+}
\ No newline at end of file
diff --git a/sdks/java/basys.sdk/src/test/resources/aas/factory/xml/in.xml b/sdks/java/basys.sdk/src/test/resources/aas/factory/xml/in.xml
index a36ecd4..31a966a 100644
--- a/sdks/java/basys.sdk/src/test/resources/aas/factory/xml/in.xml
+++ b/sdks/java/basys.sdk/src/test/resources/aas/factory/xml/in.xml
@@ -201,11 +201,12 @@
 					<aas:key type="ConceptDescription" local="true" idType="IRI">www.festo.com/dic/08111234</aas:key>
 				</aas:keys>
 			</aas:assetIdentificationModelRef>
-			<aas:kind>Instance</aas:kind>
+			<aas:kind>Type</aas:kind>
 		</aas:asset>
 		<aas:asset>
 			<aas:idShort>emptyAsset</aas:idShort>
 			<aas:identification idType="IRI">http://pk.festo.com/q30j38dlajx</aas:identification>
+			<aas:kind>Instance</aas:kind>
 		</aas:asset>
 	</aas:assets>
 	<aas:submodels>
@@ -233,34 +234,54 @@
 				</aas:keys>
 			</aas:semanticId>
 			<aas:qualifier>
-				<aas:qualifiers>
-					<aas:formula>
-						<aas:dependsOnRefs>
-							<aas:reference>
-								<aas:keys>
-									<aas:key local="false" type="GlobalReference" idType="IRDI">qualifier_reference</aas:key>
-								</aas:keys>
-							</aas:reference>
-						</aas:dependsOnRefs>
-					</aas:formula>
-				</aas:qualifiers>
-				<aas:qualifiers>
-					<aas:qualifier>
-						<aas:valueId>
+				<aas:formula>
+					<aas:dependsOnRefs>
+						<aas:reference>
 							<aas:keys>
-								<aas:key idType="IRI" local="false" type="Submodel">http://www.zvei.de/demo/submodelDefinitions/87654346</aas:key>
+								<aas:key local="false" type="GlobalReference" idType="IRDI">qualifier_reference</aas:key>
 							</aas:keys>
-						</aas:valueId>
-						<aas:value>qualifierValue</aas:value>
-						<aas:type>qualifierType</aas:type>
-						<aas:valueType>valueType</aas:valueType>
-						<aas:semanticId>
+						</aas:reference>
+					</aas:dependsOnRefs>
+				</aas:formula>
+				<aas:formula>
+					<aas:dependsOnRefs>
+						<aas:reference>
 							<aas:keys>
-								<aas:key idType="IRI" local="false" type="GlobalReference">http://www.zvei.de/demo/submodelDefinitions/87654346</aas:key>
+								<aas:key local="false" type="GlobalReference" idType="IRDI">qualifier_reference2</aas:key>
 							</aas:keys>
-						</aas:semanticId>
-					</aas:qualifier>
-				</aas:qualifiers>
+						</aas:reference>
+					</aas:dependsOnRefs>
+				</aas:formula>
+				<aas:qualifier>
+					<aas:valueId>
+						<aas:keys>
+							<aas:key idType="IRI" local="false" type="Submodel">http://www.zvei.de/demo/submodelDefinitions/87654346</aas:key>
+						</aas:keys>
+					</aas:valueId>
+					<aas:value>qualifierValue</aas:value>
+					<aas:type>qualifierType</aas:type>
+					<aas:valueType>anyType</aas:valueType>
+					<aas:semanticId>
+						<aas:keys>
+							<aas:key idType="IRI" local="false" type="GlobalReference">http://www.zvei.de/demo/submodelDefinitions/87654346</aas:key>
+						</aas:keys>
+					</aas:semanticId>
+				</aas:qualifier>
+				<aas:qualifier>
+					<aas:valueId>
+						<aas:keys>
+							<aas:key idType="IRI" local="false" type="Submodel">http://www.zvei.de/demo/submodelDefinitions/87654346</aas:key>
+						</aas:keys>
+					</aas:valueId>
+					<aas:value>qualifierValue2</aas:value>
+					<aas:type>qualifierType</aas:type>
+					<aas:valueType>anyType</aas:valueType>
+					<aas:semanticId>
+						<aas:keys>
+							<aas:key idType="IRI" local="false" type="GlobalReference">http://www.zvei.de/demo/submodelDefinitions/87654346</aas:key>
+						</aas:keys>
+					</aas:semanticId>
+				</aas:qualifier>
 			</aas:qualifier>
 			<aas:embeddedDataSpecification>
 				<aas:dataSpecificationContent>
@@ -298,23 +319,21 @@
 							</aas:keys>
 						</aas:semanticId>
 						<aas:qualifier>
-							<aas:qualifiers>
-								<aas:qualifier>
-									<aas:valueId>
-										<aas:keys>
-											<aas:key idType="IRI" local="false" type="Submodel">http://www.zvei.de/demo/submodelDefinitions/87654346</aas:key>
-										</aas:keys>
-									</aas:valueId>
-									<aas:value>qualifierValue</aas:value>
-									<aas:type>qualifierType</aas:type>
-									<aas:valueType>valueType</aas:valueType>
-									<aas:semanticId>
-										<aas:keys>
-											<aas:key idType="IRI" local="false" type="GlobalReference">http://www.zvei.de/demo/submodelDefinitions/87654346</aas:key>
-										</aas:keys>
-									</aas:semanticId>
-								</aas:qualifier>
-							</aas:qualifiers>
+							<aas:qualifier>
+								<aas:valueId>
+									<aas:keys>
+										<aas:key idType="IRI" local="false" type="Submodel">http://www.zvei.de/demo/submodelDefinitions/87654346</aas:key>
+									</aas:keys>
+								</aas:valueId>
+								<aas:value>qualifierValue</aas:value>
+								<aas:type>qualifierType</aas:type>
+								<aas:valueType>anyType</aas:valueType>
+								<aas:semanticId>
+									<aas:keys>
+										<aas:key idType="IRI" local="false" type="GlobalReference">http://www.zvei.de/demo/submodelDefinitions/87654346</aas:key>
+									</aas:keys>
+								</aas:semanticId>
+							</aas:qualifier>
 						</aas:qualifier>
 						<aas:embeddedDataSpecification>
 							<aas:dataSpecificationContent>
@@ -341,6 +360,11 @@
 								</aas:keys>
 							</aas:dataSpecification>
 						</aas:embeddedDataSpecification>
+						<aas:valueId>
+							<aas:keys>
+								<aas:key local="false" type="GlobalReference" idType="IRDI">0173-1#05-AAA650#002</aas:key>
+							</aas:keys>
+						</aas:valueId>
 						<aas:value>2000</aas:value>
 						<aas:valueType>double</aas:valueType>
 					</aas:property>
@@ -383,7 +407,7 @@
 								<aas:range>
 									<aas:idShort>range_id</aas:idShort>
 									<aas:min>10</aas:min>
-									<aas:valueType>int</aas:valueType>
+									<aas:valueType>integer</aas:valueType>
 								</aas:range>
 							</aas:submodelElement>
 						</aas:statements>
@@ -408,7 +432,7 @@
 						<aas:idShort>range_id</aas:idShort>
 						<aas:max>10</aas:max>
 						<aas:min>1</aas:min>
-						<aas:valueType>int</aas:valueType>
+						<aas:valueType>integer</aas:valueType>
 					</aas:range>
 				</aas:submodelElement>
 				<aas:submodelElement>
@@ -474,6 +498,39 @@
 					</aas:relationshipElement>
 				</aas:submodelElement>
 				<aas:submodelElement>
+					<aas:annotatedRelationshipElement>
+						<aas:idShort>annotatedRelationshipElement_ID</aas:idShort>
+						<aas:first>
+							<aas:keys>
+								<aas:key local="false" type="GlobalReference" idType="IRDI">0173-1#05-AAA650#003</aas:key>
+							</aas:keys>
+						</aas:first>
+						<aas:second>
+							<aas:keys>
+								<aas:key local="false" type="GlobalReference" idType="IRDI">0173-1#05-AAA650#004</aas:key>
+							</aas:keys>
+						</aas:second>
+						<aas:annotations>
+							<aas:dataElement>
+								<aas:property>
+									<aas:idShort>prop1</aas:idShort>
+									<aas:kind>Instance</aas:kind>
+									<aas:value>1</aas:value>
+									<aas:valueType>integer</aas:valueType>
+								</aas:property>
+							</aas:dataElement>
+							<aas:dataElement>
+								<aas:property>
+									<aas:idShort>prop2</aas:idShort>
+									<aas:kind>Instance</aas:kind>
+									<aas:value>2</aas:value>
+									<aas:valueType>integer</aas:valueType>
+								</aas:property>
+							</aas:dataElement>
+						</aas:annotations>
+					</aas:annotatedRelationshipElement>
+				</aas:submodelElement>
+				<aas:submodelElement>
 					<aas:operation>
 						<aas:idShort>operation_ID</aas:idShort>
 						<aas:inoutputVariable>
@@ -486,6 +543,7 @@
 												<aas:key local="false" type="GlobalReference" idType="IRDI">0173-1#05-AAA650#003</aas:key>
 											</aas:keys>
 										</aas:value>
+										<aas:kind>Template</aas:kind>
 									</aas:referenceElement>
 								</aas:value>
 							</aas:operationVariable>
@@ -497,6 +555,7 @@
 										<aas:idShort>file_ID</aas:idShort>
 										<aas:mimeType>file_mimetype</aas:mimeType>
 										<aas:value>file_value</aas:value>
+										<aas:kind>Template</aas:kind>
 									</aas:file>
 								</aas:value>
 							</aas:operationVariable>
@@ -506,6 +565,7 @@
 										<aas:idShort>blob_ID</aas:idShort>
 										<aas:value>YmxvYit2YWx1ZQ==</aas:value>
 										<aas:mimeType>blob_mimetype</aas:mimeType>
+										<aas:kind>Template</aas:kind>
 									</aas:blob>
 								</aas:value>
 							</aas:operationVariable>
@@ -520,6 +580,7 @@
 												<aas:key local="false" type="GlobalReference" idType="IRDI">0173-1#05-AAA650#002</aas:key>
 											</aas:keys>
 										</aas:value>
+										<aas:kind>Template</aas:kind>
 									</aas:referenceElement>
 								</aas:value>
 							</aas:operationVariable>
@@ -530,9 +591,8 @@
 		</aas:submodel>
 		<!-- This is a Submodel with only the minimal required information in it. To test for Nullpointers and such. -->
 		<aas:submodel>
-			<aas:idShort></aas:idShort>
-			<aas:identification>
-			</aas:identification>
+			<aas:idShort>testSubmodelIdShort2</aas:idShort>
+			<aas:identification idType="IRI">http://www.zvei.de/demo/submodel/12345679</aas:identification>
 			<aas:submodelElements></aas:submodelElements>
 		</aas:submodel>
 	</aas:submodels>
diff --git a/sdks/java/basys.sdk/src/test/resources/config/moquette.conf b/sdks/java/basys.sdk/src/test/resources/config/moquette.conf
new file mode 100644
index 0000000..8511afc
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/resources/config/moquette.conf
@@ -0,0 +1,6 @@
+# Moquette Java Broker configuration file for testing
+
+# Do not use the default 1883 port
+port 1884
+host 0.0.0.0
+allow_anonymous true
\ No newline at end of file
diff --git a/sdks/java/basys.sdk/tomcat.8080/resources/ssl.cert b/sdks/java/basys.sdk/tomcat.8080/resources/ssl.cert
new file mode 100644
index 0000000..d29113a
--- /dev/null
+++ b/sdks/java/basys.sdk/tomcat.8080/resources/ssl.cert
Binary files differ
diff --git a/sdks/java/basys.vabClient/.gitignore b/sdks/java/basys.vabClient/.gitignore
new file mode 100644
index 0000000..e0e5af1
--- /dev/null
+++ b/sdks/java/basys.vabClient/.gitignore
@@ -0,0 +1,72 @@
+regressiontest/
+
+.classpath
+.project
+
+test.txt
+
+target/
+pom.xml.tag
+pom.xml.releaseBackup
+pom.xml.versionsBackup
+pom.xml.next
+release.properties
+dependency-reduced-pom.xml
+buildNumber.properties
+.mvn/timing.properties
+.mvn/wrapper/maven-wrapper.jar
+.metadata
+bin/
+tmp/
+*.tmp
+*.bak
+*.swp
+*~.nib
+local.properties
+.settings/
+.loadpath
+.recommenders
+
+# External tool builders
+.externalToolBuilders/
+
+# Locally stored "Eclipse launch configurations"
+*.launch
+
+# PyDev specific (Python IDE for Eclipse)
+*.pydevproject
+
+# CDT-specific (C/C++ Development Tooling)
+.cproject
+
+# CDT- autotools
+.autotools
+
+# Java annotation processor (APT)
+.factorypath
+
+# PDT-specific (PHP Development Tools)
+.buildpath
+
+# sbteclipse plugin
+.target
+
+# Tern plugin
+.tern-project
+
+# TeXlipse plugin
+.texlipse
+
+# STS (Spring Tool Suite)
+.springBeans
+
+# Code Recommenders
+.recommenders/
+
+# Annotation Processing
+.apt_generated/
+
+# Scala IDE specific (Scala & Java development for Eclipse)
+.cache-main
+.scala_dependencies
+.worksheet
\ No newline at end of file
diff --git a/sdks/java/basys.vabClient/.project b/sdks/java/basys.vabClient/.project
new file mode 100644
index 0000000..bc25cf5
--- /dev/null
+++ b/sdks/java/basys.vabClient/.project
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>basyx.vabClient</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+	</natures>
+</projectDescription>
diff --git a/sdks/java/basys.vabClient/pom.xml b/sdks/java/basys.vabClient/pom.xml
new file mode 100644
index 0000000..13c4acf
--- /dev/null
+++ b/sdks/java/basys.vabClient/pom.xml
@@ -0,0 +1,56 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+
+	<groupId>org.eclipse.basyx</groupId>
+	<artifactId>basyx.vabClient</artifactId>
+	<version>0.0.1-SNAPSHOT</version>
+	<name>BaSyx VAB Client</name>
+
+	<packaging>jar</packaging>
+
+	<properties>
+		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+	</properties>
+
+	<build>
+		<plugins>
+			<!-- Compile Sources using Java 8 -->
+			<plugin>
+				<artifactId>maven-compiler-plugin</artifactId>
+				<version>3.8.1</version>
+				<configuration>
+					<source>1.8</source>
+					<target>1.8</target>
+				</configuration>
+			</plugin>
+		</plugins>
+	</build>
+
+	<dependencies>
+		<!-- JUnit 4 for running JUnit tests -->
+		<dependency>
+			<groupId>junit</groupId>
+			<artifactId>junit</artifactId>
+			<version>4.12</version>
+			<scope>test</scope>
+		</dependency>
+		
+		<!-- Add BaSys SDK from local repository -->
+		<dependency>
+			<groupId>org.eclipse.basyx</groupId>
+			<artifactId>basyx.sdk</artifactId>
+			<version>0.0.1-SNAPSHOT</version>
+		</dependency>
+		
+		<!-- Add test classes in BaSys SDK from local repository -->
+		<dependency>
+			<groupId>org.eclipse.basyx</groupId>
+			<artifactId>basyx.sdk</artifactId>
+			<version>0.0.1-SNAPSHOT</version>
+			<classifier>tests</classifier>
+		</dependency>
+	</dependencies>
+</project>
\ No newline at end of file
diff --git a/sdks/java/basys.vabClient/src/test/java/org/eclipse/basyx/vab/CppExceptions.java b/sdks/java/basys.vabClient/src/test/java/org/eclipse/basyx/vab/CppExceptions.java
new file mode 100644
index 0000000..2873dbb
--- /dev/null
+++ b/sdks/java/basys.vabClient/src/test/java/org/eclipse/basyx/vab/CppExceptions.java
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.vab;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import org.eclipse.basyx.vab.coder.json.metaprotocol.Message;
+import org.eclipse.basyx.vab.coder.json.metaprotocol.Result;
+import org.eclipse.basyx.vab.exception.provider.MalformedRequestException;
+import org.eclipse.basyx.vab.exception.provider.ResourceAlreadyExistsException;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.eclipse.basyx.vab.manager.VABConnectionManager;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+
+/**
+ * Snippet to test the exception handling of an IModelProvider
+ * Based on the VAB Exceptions tests within the SDK, but removes
+ * Java-specific local tests.
+ * 
+ * @author espen
+ *
+ */
+public class CppExceptions {
+	/**
+	 * Tests for handling an exception and its code
+	 */
+	public static void testHandlingException(VABConnectionManager connManager) {
+		VABElementProxy connVABElement = connManager.connectToVABElement("urn:fhg:es.iese:vab:1:1:simplevabelement");
+
+		// Empty paths - at "" is a Map. Therefore create should throw an Exception
+		try {
+			connVABElement.createValue("", "");
+			fail();
+		} catch (ResourceAlreadyExistsException e) {
+			Result result = new Result(e);
+			Message msg = result.getMessages().get(0);
+			assertEquals("422", msg.getCode());
+		}
+
+		// Non-existing parent element
+		try {
+			connVABElement.getModelPropertyValue("unknown/x");
+			fail();
+		} catch (ResourceNotFoundException e) {
+			Result result = new Result(e);
+			Message msg = result.getMessages().get(0);
+			assertEquals("404", msg.getCode());
+
+		}
+
+		// Null path - should throw exception
+		try {
+			connVABElement.createValue(null, "");
+			fail();
+		} catch (MalformedRequestException e) {
+			Result result = new Result(e);
+			Message msg = result.getMessages().get(0);
+			assertEquals("400", msg.getCode());
+		}
+
+	}
+}
diff --git a/sdks/java/basys.vabClient/src/test/java/org/eclipse/basyx/vab/CppMapInvoke.java b/sdks/java/basys.vabClient/src/test/java/org/eclipse/basyx/vab/CppMapInvoke.java
new file mode 100644
index 0000000..4658e48
--- /dev/null
+++ b/sdks/java/basys.vabClient/src/test/java/org/eclipse/basyx/vab/CppMapInvoke.java
@@ -0,0 +1,81 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.vab;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import org.eclipse.basyx.vab.exception.provider.MalformedRequestException;
+import org.eclipse.basyx.vab.exception.provider.ProviderException;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.eclipse.basyx.vab.manager.VABConnectionManager;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+
+/**
+ * Snippet to test invoke functionality of a IModelProvider.
+ * Based on the MapInvoke tests within the SDK, but removes
+ * Java-specific local tests.
+ * 
+ * @author espen
+ *
+ */
+public class CppMapInvoke {
+	
+	public static void test(VABConnectionManager connManager) {
+		// Connect to VAB element with ID "urn:fhg:es.iese:vab:1:1:simplevabelement"
+		VABElementProxy connVABElement = connManager.connectToVABElement("urn:fhg:es.iese:vab:1:1:simplevabelement");
+	
+		// Invoke complex function
+		Object complex = connVABElement.invokeOperation("operations/complex", 12, 34);
+		assertEquals(46, complex);
+	
+		// Invoke non-existing operation
+		try {
+			connVABElement.invokeOperation("operations/unknown");
+			fail();
+		} catch (ResourceNotFoundException e) {}
+	
+		// Invoke invalid operation -> not a function, but a primitive data type
+		try {
+			connVABElement.invokeOperation("operations/invalid");
+			fail();
+		} catch (ProviderException e) {}
+	
+		// Invoke operations that throw Exceptions
+		try {
+			connVABElement.invokeOperation("operations/providerException");
+			fail();
+		} catch (ProviderException e) {
+			// exception type not implemented, yet
+			// assertEquals(e.getType(), "testExceptionType");
+		}
+	
+		try {
+			connVABElement.invokeOperation("operations/nullException");
+			fail();
+		} catch (ProviderException e) {
+			// exception type not implemented, yet
+			// assertEquals(e.getType(), "java.lang.NullPointerException");
+		}
+	
+		// Empty paths - should execute, but has no effect
+		try {
+			connVABElement.invokeOperation("", "");
+			fail();
+		} catch (ProviderException e) {}
+		
+	
+		// Null path - should throw exception
+		try {
+			connVABElement.invokeOperation(null, "");
+			fail();
+		} catch (MalformedRequestException e) {}
+	}
+}
diff --git a/sdks/java/basys.vabClient/src/test/java/org/eclipse/basyx/vab/CppMapRead.java b/sdks/java/basys.vabClient/src/test/java/org/eclipse/basyx/vab/CppMapRead.java
new file mode 100644
index 0000000..b3da381
--- /dev/null
+++ b/sdks/java/basys.vabClient/src/test/java/org/eclipse/basyx/vab/CppMapRead.java
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.vab;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.fail;
+
+import java.util.Map;
+
+import org.eclipse.basyx.vab.exception.provider.MalformedRequestException;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.eclipse.basyx.vab.manager.VABConnectionManager;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+
+/**
+ * Snippet to test get functionality of a IModelProvider.
+ * Based on the MapRead tests within the SDK, but removes
+ * Java-specific local tests.
+ * 
+ * @author espen
+ *
+ */
+public class CppMapRead {
+	public static void test(VABConnectionManager connManager) {
+		// Connect to VAB element with ID "urn:fhg:es.iese:vab:1:1:simplevabelement"
+		VABElementProxy connVABElement = connManager.connectToVABElement("urn:fhg:es.iese:vab:1:1:simplevabelement");
+		
+		// Test path access
+		Object slashA = connVABElement.getModelPropertyValue("/primitives/integer");
+		Object slashB = connVABElement.getModelPropertyValue("primitives/integer/");
+		Object slashC = connVABElement.getModelPropertyValue("/primitives/integer/");
+		Object slashD = connVABElement.getModelPropertyValue("/primitives/integer/");
+		assertEquals(slashA, 123);
+		assertEquals(slashB, 123);
+		assertEquals(slashC, 123);
+		assertEquals(slashD, 123);
+		
+		// Test reading different data types
+		Object map = connVABElement.getModelPropertyValue("primitives");
+		Object doubleValue = connVABElement.getModelPropertyValue("primitives/double");
+		Object string = connVABElement.getModelPropertyValue("primitives/string");
+		assertEquals(3, ((Map<?, ?>) map).size());
+		assertEquals(3.14d, doubleValue);
+		assertEquals("TestValue", string);
+		
+		// Test case sensitivity
+		Object caseSensitiveA = connVABElement.getModelPropertyValue("special/casesensitivity");
+		Object caseSensitiveB = connVABElement.getModelPropertyValue("special/caseSensitivity");
+		assertEquals(true, caseSensitiveA);
+		assertEquals(false, caseSensitiveB);
+		
+		// Test reading null value
+		Object nullValue = connVABElement.getModelPropertyValue("special/null");
+		assertNull(nullValue);
+		
+		// Non-existing parent element
+		try {
+			connVABElement.getModelPropertyValue("unknown/x");
+			fail();
+		} catch (ResourceNotFoundException e) {}
+		
+		// Non-existing target element
+		try {
+			connVABElement.getModelPropertyValue("primitives/unkown");
+			fail();
+		} catch (ResourceNotFoundException e) {}
+		try {
+			connVABElement.getModelPropertyValue("unkown");
+			fail();
+		} catch (ResourceNotFoundException e) {}
+		
+		// Nested access
+		assertEquals(100, connVABElement.getModelPropertyValue("special/nested/nested/value"));
+		
+		// Empty path
+		Object rootValueA = connVABElement.getModelPropertyValue("");
+		Object rootValueB = connVABElement.getModelPropertyValue("/");
+		assertEquals(4, ((Map<?, ?>) rootValueA).size());
+		assertEquals(4, ((Map<?, ?>) rootValueB).size());
+		
+		// Null path - should throw exception
+		try {
+			connVABElement.getModelPropertyValue(null);
+			fail();
+		} catch (MalformedRequestException e) {}
+	}
+}
diff --git a/sdks/java/basys.vabClient/src/test/java/org/eclipse/basyx/vab/CppMapUpdate.java b/sdks/java/basys.vabClient/src/test/java/org/eclipse/basyx/vab/CppMapUpdate.java
new file mode 100644
index 0000000..c1f1f71
--- /dev/null
+++ b/sdks/java/basys.vabClient/src/test/java/org/eclipse/basyx/vab/CppMapUpdate.java
@@ -0,0 +1,86 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.vab;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import org.eclipse.basyx.vab.exception.provider.MalformedRequestException;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.eclipse.basyx.vab.manager.VABConnectionManager;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+
+/**
+ * Snippet to test set functionality of a IModelProvider.
+ * Based on the MapUpdate tests within the SDK, but removes
+ * Java-specific local tests.
+ * 
+ * @author espen
+ *
+ */
+public class CppMapUpdate {
+	public static void test(VABConnectionManager connManager) {
+		// Connect to VAB element with ID "urn:fhg:es.iese:vab:1:1:simplevabelement"
+		VABElementProxy connVABElement = connManager.connectToVABElement("urn:fhg:es.iese:vab:1:1:simplevabelement");
+		
+		// Set primitives
+		connVABElement.setModelPropertyValue("primitives/integer", 12);
+		connVABElement.setModelPropertyValue("primitives/double", 1.2d);
+		connVABElement.setModelPropertyValue("primitives/string", "updated");
+		// Read back
+		Object integer = connVABElement.getModelPropertyValue("primitives/integer");
+		Object doubleValue = connVABElement.getModelPropertyValue("primitives/double");
+		Object string = connVABElement.getModelPropertyValue("primitives/string");
+		// Test
+		assertTrue(integer instanceof Integer);
+		assertEquals(12, integer);
+		assertTrue(doubleValue instanceof Double);
+		assertEquals(1.2d, doubleValue);
+		assertTrue(string instanceof String);
+		assertEquals("updated", string);
+		// Revert
+		connVABElement.setModelPropertyValue("primitives/integer", 123);
+		connVABElement.setModelPropertyValue("primitives/double", 3.14d);
+		connVABElement.setModelPropertyValue("primitives/string", "TestValue");
+		
+		// Test non-existing parent element
+		try {
+			connVABElement.createValue("unkown/newElement", 5);
+			fail();
+		} catch (ResourceNotFoundException e) {}
+		try {
+			connVABElement.getModelPropertyValue("unknown/newElement");
+			fail();
+		} catch (ResourceNotFoundException e) {}
+		
+		// Test updating a non-existing element
+		try {
+			connVABElement.setModelPropertyValue("newElement", 10);
+			fail();
+		} catch (ResourceNotFoundException e) {
+		}
+		try {
+			connVABElement.getModelPropertyValue("newElement");
+			fail();
+		} catch (ResourceNotFoundException e) {}
+		
+		// Test updating an existing null-element
+		connVABElement.setModelPropertyValue("special/null", true);
+		Object bool = connVABElement.getModelPropertyValue("special/null");
+		assertTrue((boolean) bool);
+
+		// Null path - should throw exception
+		try {
+			connVABElement.setModelPropertyValue(null, "");
+			fail();
+		} catch (MalformedRequestException e) {}
+	}
+}
diff --git a/sdks/java/basys.vabClient/src/test/java/org/eclipse/basyx/vab/CppTestCollectionProperty.java b/sdks/java/basys.vabClient/src/test/java/org/eclipse/basyx/vab/CppTestCollectionProperty.java
new file mode 100644
index 0000000..1e56efd
--- /dev/null
+++ b/sdks/java/basys.vabClient/src/test/java/org/eclipse/basyx/vab/CppTestCollectionProperty.java
@@ -0,0 +1,124 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.vab;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.eclipse.basyx.vab.manager.VABConnectionManager;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+
+/**
+ * Tests a IModelProvider's capability to handle collections.
+ * Based on the TestCollectionProperty tests within the SDK, but removes
+ * Java-specific local tests.
+ * 
+ * @author espen
+ */
+public class CppTestCollectionProperty {
+	@SuppressWarnings("unchecked")
+	public static void testUpdate(VABConnectionManager connManager) {
+		// Connect to VAB element with ID "urn:fhg:es.iese:vab:1:1:simplevabelement"
+		VABElementProxy connVABElement = connManager.connectToVABElement("urn:fhg:es.iese:vab:1:1:simplevabelement");
+	
+		// Read original collection
+		Collection<Object> original = (Collection<Object>) connVABElement.getModelPropertyValue("/structure/list/");
+	
+		// Replace complete value of the collection property
+		Collection<Object> replacement = new ArrayList<>();
+		replacement.add(100);
+		replacement.add(200);
+		replacement.add(300);
+		connVABElement.setModelPropertyValue("/structure/list/", replacement);
+	
+		// Read values back
+		Collection<Object> collection = (Collection<Object>) connVABElement.getModelPropertyValue("/structure/list/");
+	
+		// Check test case results
+		assertEquals(3, collection.size());
+		assertEquals(replacement, collection);
+
+		// Test invalid list access - single list elements cannot be accessed directly
+		try {
+			connVABElement.setModelPropertyValue("/structure/list/0", 3);
+			fail();
+		} catch (ResourceNotFoundException e) {
+		}
+	
+		// Write original back
+		connVABElement.setModelPropertyValue("/structure/list/", original);
+	}
+
+	public static void testCreateDelete(VABConnectionManager connManager) {
+		// Connect to VAB element with ID "urn:fhg:es.iese:vab:1:1:simplevabelement"
+		VABElementProxy connVABElement = connManager.connectToVABElement("urn:fhg:es.iese:vab:1:1:simplevabelement");
+	
+		// Create elements in List (no key provided)
+		connVABElement.createValue("/structure/list/", 56);
+		Object toTest = connVABElement.getModelPropertyValue("/structure/list/");
+		assertTrue(((List<?>) toTest).contains(56));
+	
+		// Delete at List
+		// by object
+		connVABElement.deleteValue("/structure/list/", 56);
+		toTest = connVABElement.getModelPropertyValue("/structure/list/");
+		assertEquals(0, ((List<?>) toTest).size());
+	
+		// Create a list element
+		connVABElement.createValue("listInRoot", Arrays.asList(1, 1, 2, 3, 5));
+		// Test whole list
+		toTest = connVABElement.getModelPropertyValue("listInRoot");
+		assertTrue(toTest instanceof List);
+		assertEquals(5, ((List<?>) toTest).size());
+		assertEquals(2, ((List<?>) toTest).get(2));
+	
+		// Delete whole list
+		connVABElement.deleteValue("listInRoot");
+		try {
+			connVABElement.getModelPropertyValue("listInRoot");
+			fail();
+		} catch (ResourceNotFoundException e) {}
+	
+		// Delete at List
+		// - referring to new list: [10, 20, 40, 80]
+		connVABElement.createValue("/structure/list/", 10);
+		connVABElement.createValue("/structure/list/", 20);
+		connVABElement.createValue("/structure/list/", 40);
+		connVABElement.createValue("/structure/list/", 80);
+		// - by index - is not possible, as list access is only allowed using references
+		// - in contrast to indices, references always point to the same object in the list
+		try {
+			connVABElement.deleteValue("/structure/list/3");
+			fail();
+		} catch (ResourceNotFoundException e) {}
+	
+		toTest = connVABElement.getModelPropertyValue("/structure/list/");
+		assertEquals(4, ((List<?>) toTest).size());
+	
+		// Delete half of the elements
+		connVABElement.deleteValue("/structure/list/", 10);
+		connVABElement.deleteValue("/structure/list/", 40);
+		toTest = connVABElement.getModelPropertyValue("/structure/list/");
+		assertEquals(2, ((List<?>) toTest).size());
+
+		// Delete remaining elements
+		connVABElement.deleteValue("/structure/list/", 20);
+		connVABElement.deleteValue("/structure/list/", 80);
+		toTest = connVABElement.getModelPropertyValue("/structure/list/");
+		assertEquals(0, ((List<?>) toTest).size());
+	}
+}
diff --git a/sdks/java/basys.vabClient/src/test/java/org/eclipse/basyx/vab/CppTestProvider.java b/sdks/java/basys.vabClient/src/test/java/org/eclipse/basyx/vab/CppTestProvider.java
new file mode 100644
index 0000000..b9854db
--- /dev/null
+++ b/sdks/java/basys.vabClient/src/test/java/org/eclipse/basyx/vab/CppTestProvider.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.vab;
+
+import org.eclipse.basyx.testsuite.regression.vab.modelprovider.TestProvider;
+import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Abstract test suite for testing CRUD-operations for different types of model providers.
+ * The concrete test cases implement concrete VABConnectionManagers that are tested
+ * This extension supports resetting a remote VAB test server before each test.
+ * 
+ * @author espen
+ *
+ */
+public abstract class CppTestProvider extends TestProvider {
+	@Before
+	public void before() {
+		VABElementProxy connVABElement = getConnectionManager()
+				.connectToVABElement("urn:fhg:es.iese:vab:1:1:simplevabelement");
+		connVABElement.invokeOperation("/reset", 1);
+	}
+
+	@Test
+	public void testMapRead() {
+		CppMapRead.test(getConnectionManager());
+	}
+
+	@Test
+	public void testMapUpdate() {
+		CppMapUpdate.test(getConnectionManager());
+	}
+
+	@Test
+	public void testCollectionCreateDelete() throws Exception {
+		CppTestCollectionProperty.testCreateDelete(getConnectionManager());
+	}
+
+	@Test
+	public void testCollectionUpdate() {
+		CppTestCollectionProperty.testUpdate(getConnectionManager());
+	}
+
+	@Test
+	public void testMapInvoke() {
+		CppMapInvoke.test(getConnectionManager());
+	}
+
+	@Test
+	public void testHandlingException() {
+		CppExceptions.testHandlingException(getConnectionManager());
+	}
+}
diff --git a/sdks/java/basys.vabClient/src/test/java/org/eclipse/basyx/vab/CppVABTestApplication.java b/sdks/java/basys.vabClient/src/test/java/org/eclipse/basyx/vab/CppVABTestApplication.java
new file mode 100644
index 0000000..9c76317
--- /dev/null
+++ b/sdks/java/basys.vabClient/src/test/java/org/eclipse/basyx/vab/CppVABTestApplication.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.vab;
+
+import org.eclipse.basyx.testsuite.regression.aas.aggregator.AASAggregatorSuite;
+import org.junit.internal.TextListener;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Result;
+
+/**
+ * The main class that executes the test provider.
+ * Structure is based on the TCK
+ * 
+ * @author espen
+ *
+ */
+public class CppVABTestApplication {
+
+	public static void main(String[] args) {
+		// First argument is the inserted url
+		String url = args[0];
+		// Run junit test in a java application
+		JUnitCore junit = new JUnitCore();
+		junit.addListener(new TextListener(System.out));
+
+		VABClientTest.url = url;
+		Result result = junit.run(AASAggregatorSuite.class);
+
+		System.out.println("Finished. Result: Failures: " +
+				result.getFailureCount() + ". Ignored: " +
+				result.getIgnoreCount() + ". Tests run: " +
+				result.getRunCount() + ". Time: " +
+				result.getRunTime() + "ms.");
+	}
+
+}
diff --git a/sdks/java/basys.vabClient/src/test/java/org/eclipse/basyx/vab/VABClientTest.java b/sdks/java/basys.vabClient/src/test/java/org/eclipse/basyx/vab/VABClientTest.java
new file mode 100644
index 0000000..d8e47d7
--- /dev/null
+++ b/sdks/java/basys.vabClient/src/test/java/org/eclipse/basyx/vab/VABClientTest.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.vab;
+
+import org.eclipse.basyx.vab.directory.api.IVABDirectoryService;
+import org.eclipse.basyx.vab.directory.memory.InMemoryDirectory;
+import org.eclipse.basyx.vab.manager.VABConnectionManager;
+import org.eclipse.basyx.vab.protocol.basyx.connector.BaSyxConnectorProvider;
+
+/**
+ * The client side for a Java-Cpp integration test
+ * 
+ * @author espen
+ *
+ */
+public class VABClientTest extends CppTestProvider {
+	public static String url = "basyx://localhost:8384/";
+
+	protected VABConnectionManager connManager;
+
+	public VABClientTest() {
+		// Setup the directory based on the SDK-VAB tests
+		IVABDirectoryService directory = new InMemoryDirectory();
+		String simpleVABID = "urn:fhg:es.iese:vab:1:1:simplevabelement";
+		directory.addMapping(simpleVABID, url);
+		connManager = new VABConnectionManager(directory, new BaSyxConnectorProvider());
+	}
+
+	@Override
+	protected VABConnectionManager getConnectionManager() {
+		return connManager;
+	}
+}
diff --git a/sdks/java/basys.vabServer/.gitignore b/sdks/java/basys.vabServer/.gitignore
new file mode 100644
index 0000000..e0e5af1
--- /dev/null
+++ b/sdks/java/basys.vabServer/.gitignore
@@ -0,0 +1,72 @@
+regressiontest/
+
+.classpath
+.project
+
+test.txt
+
+target/
+pom.xml.tag
+pom.xml.releaseBackup
+pom.xml.versionsBackup
+pom.xml.next
+release.properties
+dependency-reduced-pom.xml
+buildNumber.properties
+.mvn/timing.properties
+.mvn/wrapper/maven-wrapper.jar
+.metadata
+bin/
+tmp/
+*.tmp
+*.bak
+*.swp
+*~.nib
+local.properties
+.settings/
+.loadpath
+.recommenders
+
+# External tool builders
+.externalToolBuilders/
+
+# Locally stored "Eclipse launch configurations"
+*.launch
+
+# PyDev specific (Python IDE for Eclipse)
+*.pydevproject
+
+# CDT-specific (C/C++ Development Tooling)
+.cproject
+
+# CDT- autotools
+.autotools
+
+# Java annotation processor (APT)
+.factorypath
+
+# PDT-specific (PHP Development Tools)
+.buildpath
+
+# sbteclipse plugin
+.target
+
+# Tern plugin
+.tern-project
+
+# TeXlipse plugin
+.texlipse
+
+# STS (Spring Tool Suite)
+.springBeans
+
+# Code Recommenders
+.recommenders/
+
+# Annotation Processing
+.apt_generated/
+
+# Scala IDE specific (Scala & Java development for Eclipse)
+.cache-main
+.scala_dependencies
+.worksheet
\ No newline at end of file
diff --git a/sdks/java/basys.vabServer/pom.xml b/sdks/java/basys.vabServer/pom.xml
new file mode 100644
index 0000000..b4e090b
--- /dev/null
+++ b/sdks/java/basys.vabServer/pom.xml
@@ -0,0 +1,80 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+
+	<groupId>org.eclipse.basyx</groupId>
+	<artifactId>basyx.vabServer</artifactId>
+	<version>0.0.1-SNAPSHOT</version>
+	<name>BaSyx VAB Server</name>
+
+	<packaging>jar</packaging>
+
+	<properties>
+		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+		<exec.mainClass></exec.mainClass>
+	</properties>
+
+	<build>
+		<plugins>
+			<!-- Compile Sources using Java 8 -->
+			<plugin>
+				<artifactId>maven-compiler-plugin</artifactId>
+				<version>3.8.1</version>
+				<configuration>
+					<source>1.8</source>
+					<target>1.8</target>
+				</configuration>
+			</plugin>
+			
+				<!-- Generate separate jar for tests and exclude logback.xml from generated jars -->
+				<!-- + create the executable jar -->
+				<plugin>
+					<groupId>org.apache.maven.plugins</groupId>
+					<artifactId>maven-jar-plugin</artifactId>
+					<version>3.1.1</version>
+					<configuration>
+						<archive>
+							<manifest>
+								<addClasspath>true</addClasspath>
+								<classpathPrefix>lib/</classpathPrefix>
+								<mainClass>ServerApplication</mainClass>
+							</manifest>
+						</archive>
+						<excludes>
+							<exclude>**/logback.xml</exclude>
+						</excludes>
+					</configuration>
+				</plugin>
+				
+				<!-- Copy the dependencies necessary to run the jar -->
+				<plugin>
+					<groupId>org.apache.maven.plugins</groupId>
+					<artifactId>maven-dependency-plugin</artifactId>
+					<executions>
+						<execution>
+							<id>copy-dependencies</id>
+							<phase>prepare-package</phase>
+							<goals>
+								<goal>copy-dependencies</goal>
+							</goals>
+							<configuration>
+								<includeScope>compile</includeScope>
+								<outputDirectory>${project.build.directory}/lib/</outputDirectory>
+							</configuration>
+						</execution>
+					</executions>
+				</plugin>
+		</plugins>
+	</build>
+
+	<dependencies>
+		<!-- Add BaSys SDK from local repository. SDK has to be installed previously -->
+		<dependency>
+			<groupId>org.eclipse.basyx</groupId>
+			<artifactId>basyx.sdk</artifactId>
+			<version>0.0.1-SNAPSHOT</version>
+		</dependency>
+	</dependencies>
+</project>
\ No newline at end of file
diff --git a/sdks/java/basys.vabServer/src/main/java/org/eclipse/basyx/vab/ServerApplication.java b/sdks/java/basys.vabServer/src/main/java/org/eclipse/basyx/vab/ServerApplication.java
new file mode 100644
index 0000000..5d65361
--- /dev/null
+++ b/sdks/java/basys.vabServer/src/main/java/org/eclipse/basyx/vab/ServerApplication.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.vab;
+
+import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
+import org.eclipse.basyx.vab.protocol.basyx.server.BaSyxTCPServer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A server application that provides a generic VAB-object that can be reset
+ * 
+ * @author espen
+ *
+ */
+public class ServerApplication {
+	private static Logger logger = LoggerFactory.getLogger(ServerApplication.class);
+
+	private static BaSyxTCPServer<IModelProvider> server;
+
+	public static void main(String[] args) {
+		int port = 8383;
+		if (args.length > 0) {
+			// First argument is the port
+			port = Integer.parseInt(args[0]);
+			logger.info("Starting server at port " + port);
+		} else {
+			logger.info("Starting server at default port " + port);
+		}
+
+		server = new BaSyxTCPServer<>(new SimpleVABProvider(), port);
+		server.start();
+	}
+}
diff --git a/sdks/java/basys.vabServer/src/main/java/org/eclipse/basyx/vab/SimpleVABElement.java b/sdks/java/basys.vabServer/src/main/java/org/eclipse/basyx/vab/SimpleVABElement.java
new file mode 100644
index 0000000..0df586e
--- /dev/null
+++ b/sdks/java/basys.vabServer/src/main/java/org/eclipse/basyx/vab/SimpleVABElement.java
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.vab;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.function.Function;
+
+import org.eclipse.basyx.vab.exception.provider.ProviderException;
+
+/**
+ * A simple VAB model that explains the use of the VAB primitives.
+ * Removes local Java-specific properties (e.g. function serialization)
+ * 
+ * @author espen
+ *
+ */
+public class SimpleVABElement extends HashMap<String, Object> {
+	private static final long serialVersionUID = 3942399852711325850L;
+
+	/**
+	 * Constructor for a simple VAB element that contains all data types
+	 */
+	public SimpleVABElement() {
+		// Add primitive types
+		HashMap<String, Object> primitives = new HashMap<>();
+		primitives.put("integer", 123);
+		primitives.put("double", 3.14d);
+		primitives.put("string", "TestValue");
+		put("primitives", primitives);
+
+		// Add function types
+		HashMap<String, Object> functions = new HashMap<>();
+		functions.put("providerException", (Function<Object[], Object>) (param) -> {
+			throw new ProviderException("Exception description");
+		});
+		functions.put("nullException", (Function<Object[], Object>) (param) -> {
+			throw new NullPointerException();
+		});
+		functions.put("complex", (Function<Object[], Object>) (param) -> {
+			return (int) param[0] + (int) param[1];
+		});
+		functions.put("invalid", true);
+		functions.put("invokable", (Function<Object[], Object>) (param) -> {
+			return true;
+		});
+		put("operations", functions);
+
+		// Add structure types
+		HashMap<String, Object> structure = new HashMap<>();
+		structure.put("map", new HashMap<String, Object>());
+		structure.put("list", new ArrayList<Object>());
+		put("structure", structure);
+
+		// Add corner cases
+		HashMap<String, Object> special = new HashMap<>();
+		special.put("casesensitivity", true);
+		special.put("caseSensitivity", false);
+		HashMap<String, Object> nestedA = new HashMap<>();
+		HashMap<String, Object> nestedB = new HashMap<>();
+		nestedA.put("nested", nestedB);
+		nestedB.put("value", 100);
+		special.put("nested", nestedA);
+		special.put("null", null);
+		put("special", special);
+	}
+}
diff --git a/sdks/java/basys.vabServer/src/main/java/org/eclipse/basyx/vab/SimpleVABProvider.java b/sdks/java/basys.vabServer/src/main/java/org/eclipse/basyx/vab/SimpleVABProvider.java
new file mode 100644
index 0000000..0081ad2
--- /dev/null
+++ b/sdks/java/basys.vabServer/src/main/java/org/eclipse/basyx/vab/SimpleVABProvider.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ ******************************************************************************/
+package org.eclipse.basyx.vab;
+
+import org.eclipse.basyx.vab.modelprovider.VABPathTools;
+import org.eclipse.basyx.vab.modelprovider.map.VABMapProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Provider that contains a SimpleVABElement for testing purposes that can be reset.
+ * For this, invoke the provider at path /reset with any parameter.
+ * 
+ * @author espen
+ *
+ */
+public class SimpleVABProvider extends VABMapProvider {
+	private static Logger logger = LoggerFactory.getLogger(SimpleVABProvider.class);
+
+	public SimpleVABProvider() {
+		super(new SimpleVABElement());
+	}
+
+	/**
+	 * Adds a "reset" operation to reset the SimpleVABElement at /reset
+	 */
+	@Override
+	public Object invokeOperation(String path, Object... parameters) {
+		logger.info("Invoke path: " + path);
+		if (path == null) {
+			return super.invokeOperation(path, parameters);
+		}
+		String[] parts = VABPathTools.splitPath(path);
+		String lastElement = VABPathTools.getLastElement(path);
+		if (parts.length == 1 && lastElement.equals("reset")) {
+			super.elements = new SimpleVABElement();
+			logger.info("Reset element");
+			return null;
+		} else {
+			return super.invokeOperation(path, parameters);
+		}
+	}
+}
diff --git a/tools/cpp-enum-generator/enums/KeyElements b/tools/cpp-enum-generator/enums/KeyElements
deleted file mode 100644
index 3c16805..0000000
--- a/tools/cpp-enum-generator/enums/KeyElements
+++ /dev/null
@@ -1,26 +0,0 @@
-GlobalReference
-FragmentReference
-AccessPermissionRule
-AnnotatedRelationshipElement
-BasicEvent
-Blob
-Capability
-ConceptDictionary
-DataElement
-Entity
-Event
-File
-MultiLanguageProperty
-Operation
-Property
-Range
-ReferenceElement
-RelationshipElement
-SubmodelElement
-SubmodelElementCollection
-View
-Unknown
-Asset
-AssetAdministrationShell
-ConceptDescription
-Submodel
diff --git a/tools/cpp-enum-generator/enums_control-components/ExecutionOrder b/tools/cpp-enum-generator/enums_control-components/ExecutionOrder
new file mode 100644
index 0000000..65d9f68
--- /dev/null
+++ b/tools/cpp-enum-generator/enums_control-components/ExecutionOrder
@@ -0,0 +1,10 @@
+start
+complete
+reset
+hold
+unhold
+suspend
+unsuspend
+clear
+stop
+abort
diff --git a/tools/cpp-enum-generator/enums_control-components/ExecutionState b/tools/cpp-enum-generator/enums_control-components/ExecutionState
new file mode 100644
index 0000000..3d8ed05
--- /dev/null
+++ b/tools/cpp-enum-generator/enums_control-components/ExecutionState
@@ -0,0 +1,17 @@
+idle
+starting
+execute
+completing
+complete
+resetting
+holding
+held
+unholding
+suspending
+suspended
+unsuspending
+stopping
+stopped
+aborting
+aborted
+clearing
diff --git a/tools/cpp-enum-generator/enums/AssetKind b/tools/cpp-enum-generator/enums_submodel/AssetKind
similarity index 100%
rename from tools/cpp-enum-generator/enums/AssetKind
rename to tools/cpp-enum-generator/enums_submodel/AssetKind
diff --git a/tools/cpp-enum-generator/enums/DataTypeIEC61360 b/tools/cpp-enum-generator/enums_submodel/DataTypeIEC61360
similarity index 100%
rename from tools/cpp-enum-generator/enums/DataTypeIEC61360
rename to tools/cpp-enum-generator/enums_submodel/DataTypeIEC61360
diff --git a/tools/cpp-enum-generator/enums/EntityType b/tools/cpp-enum-generator/enums_submodel/EntityType
similarity index 100%
rename from tools/cpp-enum-generator/enums/EntityType
rename to tools/cpp-enum-generator/enums_submodel/EntityType
diff --git a/tools/cpp-enum-generator/enums/IdentifiableElements b/tools/cpp-enum-generator/enums_submodel/IdentifiableElements
similarity index 100%
rename from tools/cpp-enum-generator/enums/IdentifiableElements
rename to tools/cpp-enum-generator/enums_submodel/IdentifiableElements
diff --git a/tools/cpp-enum-generator/enums/IdentifierType b/tools/cpp-enum-generator/enums_submodel/IdentifierType
similarity index 100%
rename from tools/cpp-enum-generator/enums/IdentifierType
rename to tools/cpp-enum-generator/enums_submodel/IdentifierType
diff --git a/tools/cpp-enum-generator/enums_submodel/KeyElements b/tools/cpp-enum-generator/enums_submodel/KeyElements
new file mode 100644
index 0000000..c88a558
--- /dev/null
+++ b/tools/cpp-enum-generator/enums_submodel/KeyElements
@@ -0,0 +1,27 @@
+GlobalReference
+FragmentReference
+AccessPermissionRule
+AnnotatedRelationshipElement
+BasicEvent
+Blob
+Capability
+ConceptDictionary
+DataElement
+Entity
+Event
+File
+MultiLanguageProperty
+Operation
+OperationVariable
+Property
+Range
+ReferenceElement
+RelationshipElement
+SubmodelElement
+SubmodelElementCollection
+View
+Unknown
+Asset
+AssetAdministrationShell
+ConceptDescription
+Submodel
diff --git a/tools/cpp-enum-generator/enums/KeyType b/tools/cpp-enum-generator/enums_submodel/KeyType
similarity index 100%
rename from tools/cpp-enum-generator/enums/KeyType
rename to tools/cpp-enum-generator/enums_submodel/KeyType
diff --git a/tools/cpp-enum-generator/enums/LevelType b/tools/cpp-enum-generator/enums_submodel/LevelType
similarity index 100%
rename from tools/cpp-enum-generator/enums/LevelType
rename to tools/cpp-enum-generator/enums_submodel/LevelType
diff --git a/tools/cpp-enum-generator/enums/LocalKeyType b/tools/cpp-enum-generator/enums_submodel/LocalKeyType
similarity index 100%
rename from tools/cpp-enum-generator/enums/LocalKeyType
rename to tools/cpp-enum-generator/enums_submodel/LocalKeyType
diff --git a/tools/cpp-enum-generator/enums/ModelTypes b/tools/cpp-enum-generator/enums_submodel/ModelTypes
similarity index 100%
rename from tools/cpp-enum-generator/enums/ModelTypes
rename to tools/cpp-enum-generator/enums_submodel/ModelTypes
diff --git a/tools/cpp-enum-generator/enums/ModelingKind b/tools/cpp-enum-generator/enums_submodel/ModelingKind
similarity index 100%
rename from tools/cpp-enum-generator/enums/ModelingKind
rename to tools/cpp-enum-generator/enums_submodel/ModelingKind
diff --git a/tools/cpp-enum-generator/enums/ReferableElements b/tools/cpp-enum-generator/enums_submodel/ReferableElements
similarity index 100%
rename from tools/cpp-enum-generator/enums/ReferableElements
rename to tools/cpp-enum-generator/enums_submodel/ReferableElements
diff --git a/tools/cpp-enum-generator/generate_enums.sh b/tools/cpp-enum-generator/generate_enums.sh
old mode 100644
new mode 100755
index 45690b2..f8f76c3
--- a/tools/cpp-enum-generator/generate_enums.sh
+++ b/tools/cpp-enum-generator/generate_enums.sh
@@ -4,7 +4,7 @@
 TARGET_SRC_DIR=$CPP_SDK_DIR/src/submodel/submodel/enumerations
 TARGET_HEADER_DIR=$CPP_SDK_DIR/include/BaSyx/submodel/enumerations/
 
-ENUMS_DIR=enums
+ENUMS_DIR=enums_submodel
 OUT_DIR=generated
 
 TEMPLATE=template.txt
@@ -20,3 +20,24 @@
 
 mv $OUT_DIR/*.cpp $TARGET_SRC_DIR
 mv $OUT_DIR/*.h $TARGET_HEADER_DIR
+
+
+TARGET_SRC_DIR=$CPP_SDK_DIR/src/controlcomponent/enumerations
+TARGET_HEADER_DIR=$CPP_SDK_DIR/include/BaSyx/controlcomponent/enumerations/
+
+ENUMS_DIR=enums_control-components
+OUT_DIR=generated
+
+TEMPLATE=template_control-components.txt
+
+mkdir -p $OUT_DIR
+mkdir -p $TARGET_SRC_DIR
+mkdir -p $TARGET_HEADER_DIR
+
+for f in $ENUMS_DIR/*; do
+    python3 generator.py -t $TEMPLATE -o $OUT_DIR $f
+done
+
+
+mv $OUT_DIR/*.cpp $TARGET_SRC_DIR
+mv $OUT_DIR/*.h $TARGET_HEADER_DIR
diff --git a/tools/cpp-enum-generator/generator.py b/tools/cpp-enum-generator/generator.py
index 88b3ce9..d97d2d8 100755
--- a/tools/cpp-enum-generator/generator.py
+++ b/tools/cpp-enum-generator/generator.py
@@ -54,6 +54,7 @@
             for line_template in line_templates:
                 line = line_template + "\n"
                 line = line.replace("$ENUM_CLASS$", self.enum_class)
+                line = line.replace("$ENUM_CLASS_CAP$", self.enum_class.upper())
                 line = line.replace("$SIZE$", str(self.size))
                 for constant in self.constants.keys():
                     line = line.replace(constant, self.constants[constant])
diff --git a/tools/cpp-enum-generator/template.txt b/tools/cpp-enum-generator/template.txt
index 016901c..359899b 100644
--- a/tools/cpp-enum-generator/template.txt
+++ b/tools/cpp-enum-generator/template.txt
@@ -3,6 +3,7 @@
 ; at the end of the file. i.e.: "$FILE_ENDING cpp". If $FILE_ENDING$ is not set, ".hpp" will be used.
 ; Other tags that can be used are:
 ; $ENUM_CLASS$  : Class name of enum, obtained from file name
+; $ENUM_CLASS_CAP$ : Class name of enum in uppercase
 ; $FIRST_ENUM$  : The first enum in the list of enums
 ; $MIDDLE_ENUM$ : All enums that are in between first and last enum.
 ; $LAST_ENUM$   : The last enum in the list of enums
@@ -11,8 +12,8 @@
 ;
 ;
 $CONSTANT$ NAMESPACE submodel
-#ifndef BASYX_SUBMODEL_ENUM_$ENUM_CLASS$_H
-#define BASYX_SUBMODEL_ENUM_$ENUM_CLASS$_H
+#ifndef BASYX_SUBMODEL_ENUMERATIONS_$ENUM_CLASS_CAP$_H
+#define BASYX_SUBMODEL_ENUMERATIONS_$ENUM_CLASS_CAP$_H
 
 #include <string>
 
@@ -36,7 +37,7 @@
 }
 }
 
-#endif
+#endif /* BASYX_SUBMODEL_ENUMERATIONS_$ENUM_CLASS_CAP$_H */
 $FILE_ENDING$ h
 #include <BaSyx/$NAMESPACE$/enumerations/$ENUM_CLASS$.h>
 
diff --git a/tools/cpp-enum-generator/template_control-components.txt b/tools/cpp-enum-generator/template_control-components.txt
new file mode 100644
index 0000000..ee054a9
--- /dev/null
+++ b/tools/cpp-enum-generator/template_control-components.txt
@@ -0,0 +1,80 @@
+; Comments must start with ; all other lines will be present in the corresponding file
+; Indicate a source-code file by $FILE_ENDING$-tag and the corresponding file ending
+; at the end of the file. i.e.: "$FILE_ENDING cpp". If $FILE_ENDING$ is not set, ".hpp" will be used.
+; Other tags that can be used are:
+; $ENUM_CLASS$     : Class name of enum, obtained from file name
+; $ENUM_CLASS_CAP$ : Class name of enum in uppercase
+; $FIRST_ENUM$     : The first enum in the list of enums
+; $MIDDLE_ENUM$    : All enums that are in between first and last enum.
+; $LAST_ENUM$      : The last enum in the list of enums
+; $SIZE$           : The number of enums
+; $CONSTANT$       : Define a costant, i.e.: $CONSTSANT$ NAME value, usage in document with $NAME$
+;
+;
+$CONSTANT$ NAMESPACE controlcomponent
+#ifndef BASYX_CONTROLCOMPONENT_ENUM_$ENUM_CLASS_CAP$_H
+#define BASYX_CONTROLCOMPONENT_ENUM_$ENUM_CLASS_CAP$_H
+
+#include <string>
+
+namespace basyx {
+namespace $NAMESPACE$ {
+
+enum class $ENUM_CLASS$ {
+    $FIRST_ENUM$,
+    $MIDDLE_ENUM$,
+    $LAST_ENUM$,
+};
+
+class $ENUM_CLASS$_
+{
+public:
+    static $ENUM_CLASS$ from_string(const std::string & name);
+    static const char * to_string($ENUM_CLASS$ value);
+};
+
+
+}
+}
+
+#endif
+$FILE_ENDING$ h
+#include <BaSyx/$NAMESPACE$/enumerations/$ENUM_CLASS$.h>
+
+#include <array>
+#include <algorithm>
+#include <memory>
+#include <string>
+
+using namespace basyx::controlcomponent;
+
+using enum_pair_t = std::pair<const char*, $ENUM_CLASS$>;
+
+static const std::array<enum_pair_t, $SIZE$> string_to_enum = 
+{
+    std::make_pair("$FIRST_ENUM$",  $ENUM_CLASS$::$FIRST_ENUM$),
+    std::make_pair("$MIDDLE_ENUM$", $ENUM_CLASS$::$MIDDLE_ENUM$),
+    std::make_pair("$LAST_ENUM$", $ENUM_CLASS$::$LAST_ENUM$),
+};
+
+$ENUM_CLASS$ $ENUM_CLASS$_::from_string(const std::string & name)
+{
+    auto pair = std::find_if(string_to_enum.begin(), string_to_enum.end(), 
+		[&name](const enum_pair_t & pair) {
+			return !name.compare(pair.first);
+	});
+
+    return pair->second;
+}
+
+const char * $ENUM_CLASS$_::to_string($ENUM_CLASS$ value)
+{
+    auto pair = std::find_if(string_to_enum.begin(), string_to_enum.end(), 
+		[value](const enum_pair_t & pair) {
+			return value == pair.second;
+	});
+
+    return pair->first;
+}
+
+$FILE_ENDING$ cpp