Merging changes from 'master' branch into 'cpp' branch

Change-Id: I5ad63ef3cd9e437afd8036e7f61ffb6c929cc6cb
Signed-off-by: Thomas Psota <thomas.psota@iese.fraunhofer.de>
diff --git a/.gitignore b/.gitignore
index b2e90d3..2124e28 100644
--- a/.gitignore
+++ b/.gitignore
@@ -58,3 +58,4 @@
 /.vs
 /sdks/dotnet/.vs/BaSyx
 launchSettings.json
+.project
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/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.mongodbregistry/docker-compose.yml b/components/basys.components/basyx.components.docker/basyx.components.AASServer/docker-compose.yml
similarity index 97%
rename from components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/docker-compose.yml
rename to components/basys.components/basyx.components.docker/basyx.components.AASServer/docker-compose.yml
index 8daf8d6..b55d107 100644
--- a/components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/docker-compose.yml
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/docker-compose.yml
@@ -1,6 +1,7 @@
 version: '2.1'
 services:
-  registry:
+
+  aas:
     image: ${BASYX_IMAGE_NAME}:${BASYX_IMAGE_TAG}
     container_name: ${BASYX_CONTAINER_NAME}
     ports:
@@ -14,12 +15,12 @@
   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
+      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..88e4939 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>0.1.0-SNAPSHOT</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,29 @@
 		</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>
+	</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..68979fa
--- /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,276 @@
+package org.eclipse.basyx.components.aas;
+
+import java.io.IOException;
+import java.net.URISyntaxException;
+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.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.IAASRegistryService;
+import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
+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.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.xml.XMLAASBundleFactory;
+import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
+import org.eclipse.basyx.support.bundle.AASBundle;
+import org.eclipse.basyx.support.bundle.AASBundleDescriptorFactory;
+import org.eclipse.basyx.support.bundle.AASBundleIntegrator;
+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}/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 AASHTTPServer server;
+	private IAASRegistryService registry;
+
+	// Configurations
+	private BaSyxContextConfiguration contextConfig;
+	private BaSyxAASServerConfiguration aasConfig;
+	private BaSyxMongoDBConfiguration mongoDBConfig;
+
+	// 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;
+	}
+
+	public void setRegistry(IAASRegistryService 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
+		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("/aasx/*", new DefaultServlet());
+
+			// 2. Fix the file paths according to the servlet configuration
+			modifyFilePaths(contextConfig.getHostname(), contextConfig.getPort(), contextConfig.getContextPath());
+
+			// 3. Create registry & register the initial AAS
+			createRegistryFromUrl();
+			registerAAS();
+		}
+
+		logger.info("Start the server");
+		server = new AASHTTPServer(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() {
+		server.shutdown();
+	}
+
+	private void loadBundleFromXML(String xmlPath) throws IOException, ParserConfigurationException, SAXException {
+		logger.info("Loading aas from xml \"" + xmlPath + "\"");
+		String xmlContent = BaSyxConfiguration.getResourceString(xmlPath);
+		this.aasBundles = new XMLAASBundleFactory(xmlContent).create();
+	}
+
+	private void loadBundleFromAASX(String aasxPath)
+			throws IOException, ParserConfigurationException, SAXException, URISyntaxException {
+		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(aasxPath);
+
+		// 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) {
+			AASBundleIntegrator.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(".xml")) {
+				loadBundleFromXML(aasSource);
+			}
+		} catch (IOException | ParserConfigurationException | SAXException | URISyntaxException e) {
+			logger.error("Could not load initial AAS from source " + aasSource);
+			e.printStackTrace();
+		}
+	}
+
+	/**
+	 * 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) {
+		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 ) {
+			logger.info("Using InMemory backend");
+			aggregator = new AASAggregator(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.AASX/src/main/java/org/eclipse/basyx/components/aasx/AASXPackageManager.java b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/aasx/AASXPackageManager.java
similarity index 93%
rename from components/basys.components/basyx.components.docker/basyx.components.AASX/src/main/java/org/eclipse/basyx/components/aasx/AASXPackageManager.java
rename to components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/aasx/AASXPackageManager.java
index 485b391..7cfba6f 100644
--- 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.AASServer/src/main/java/org/eclipse/basyx/components/aas/aasx/AASXPackageManager.java
@@ -1,6 +1,7 @@
-package org.eclipse.basyx.components.aasx;
+package org.eclipse.basyx.components.aas.aasx;
 
 import java.io.File;
+import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
@@ -185,13 +186,13 @@
 	private String getXMLResourceString(String filePath) throws IOException, ParserConfigurationException, SAXException {
 		String aasXmlPath;
 		// Create the zip input stream
-		try (ZipInputStream stream = new ZipInputStream(BaSyxConfiguration.getResourceStream(filePath))) {
+		try (ZipInputStream stream = getZipInputStream(filePath)) {
 
 			// find the path of the aas xml
 			aasXmlPath = this.findAASXml(stream);
 		}
 
-		try (ZipInputStream stream = new ZipInputStream(BaSyxConfiguration.getResourceStream(filePath))) {
+		try (ZipInputStream stream = getZipInputStream(filePath)) {
 			// Find the entry of the aas xml
 			ZipInputStream streamPointingToEntry = this.returnFileEntryStream(aasXmlPath, stream);
 
@@ -215,12 +216,12 @@
 			throws IOException, ParserConfigurationException, SAXException {
 		String xmlPath;
 		logger.info("AASX filepath: " + aasxFilePath);
-		try (ZipInputStream stream = new ZipInputStream(BaSyxConfiguration.getResourceStream(aasxFilePath))) {
+		try (ZipInputStream stream = getZipInputStream(aasxFilePath)) {
 			// find the aasx xml file
 			xmlPath = this.findAASXml(stream);
 		}
 
-		try (ZipInputStream stream = new ZipInputStream(BaSyxConfiguration.getResourceStream(aasxFilePath))) {
+		try (ZipInputStream stream = getZipInputStream(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";
@@ -291,7 +292,7 @@
 		byte[] buffer = new byte[1024];
 
 		// Find the file with the "filePath"
-		try (ZipInputStream stream = new ZipInputStream(BaSyxConfiguration.getResourceStream(aasxPath))) {
+		try (ZipInputStream stream = getZipInputStream(aasxPath)) {
 			ZipEntry zipEntry = stream.getNextEntry();
 			while (zipEntry != null) {
 				if (!zipEntry.isDirectory() && zipEntry.getName().contains(filePath)) {
@@ -373,4 +374,13 @@
 		}
 		return files;
 	}
+
+	private ZipInputStream getZipInputStream(String aasxFilePath) throws IOException {
+		try {
+			return new ZipInputStream(BaSyxConfiguration.getResourceStream(aasxFilePath));
+		} catch (NullPointerException ex) {
+			// Alternativ, if resource has not been found: load from a file
+			return new ZipInputStream(new FileInputStream(aasxFilePath));
+		}
+	}
 }
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..df341ca
--- /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,82 @@
+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/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..cfbddbc
--- /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,52 @@
+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..f0a29ca
--- /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,93 @@
+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 {
+	// 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 = "";
+
+	// Configuration keys
+	public static final String REGISTRY = "registry.path";
+	public static final String BACKEND = "aas.backend";
+	public static final String SOURCE = "aas.source";
+
+	// 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);
+		return defaultProps;
+	}
+
+	/**
+	 * Empty Constructor - use default values
+	 */
+	public BaSyxAASServerConfiguration() {
+		super(getDefaultProperties());
+	}
+
+	/**
+	 * Constructor with initial configuration - docBasePath and hostname are default values
+	 * 
+	 * @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 predefined value map
+	 */
+	public BaSyxAASServerConfiguration(Map<String, String> values) {
+		super(values);
+	}
+
+	public void loadFromDefaultSource() {
+		loadFileOrDefaultResource(DEFAULT_FILE_KEY, DEFAULT_CONFIG_PATH);
+	}
+
+	public AASServerBackend getAASBackend() {
+		return AASServerBackend.fromString(getProperty(BACKEND));
+	}
+
+	public void setAASBackend(AASServerBackend backend) {
+		setProperty(BACKEND, backend.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..cd3a3e9
--- /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,47 @@
+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.BaSyxAASServerConfiguration;
+import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
+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);
+		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..99ae7c4
--- /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,155 @@
+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);
+	}
+
+	@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);
+	}
+
+}
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..5c37004
--- /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,240 @@
+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.IAASRegistryService;
+import org.eclipse.basyx.aas.restapi.AASModelProvider;
+import org.eclipse.basyx.aas.restapi.VABMultiSubmodelProvider;
+import org.eclipse.basyx.aas.restapi.api.IAASAPI;
+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.vab.exception.provider.ResourceNotFoundException;
+import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
+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, VABMultiSubmodelProvider> aasProviderMap = new HashMap<>();
+	protected BaSyxMongoDBConfiguration config;
+	protected MongoOperations mongoOps;
+	protected String aasCollection;
+	protected String smCollection;
+
+	private IAASRegistryService registry;
+
+	/**
+	 * 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(IAASRegistryService 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) {
+		this.config = config;
+		MongoClient client = MongoClients.create(config.getConnectionUrl());
+		this.mongoOps = new MongoTemplate(client, config.getDatabase());
+		this.aasCollection = config.getAASCollection();
+		this.smCollection = config.getSubmodelCollection();
+	}
+
+	/**
+	 * 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) {
+			logger.info("Adding AAS from DB: " + aas.getIdentification().getId());
+			VABMultiSubmodelProvider provider = createMultiSubmodelProvider(aas);
+			aasProviderMap.put(aas.getIdentification().getId(), provider);
+		}
+	}
+
+	private VABMultiSubmodelProvider createMultiSubmodelProvider(AssetAdministrationShell aas) {
+		IAASAPI aasApi = new MongoDBAASAPI(config, aas.getIdentification().getId());
+		AASModelProvider aasProvider = new AASModelProvider(aasApi);
+		VABMultiSubmodelProvider provider = new VABMultiSubmodelProvider(aasProvider, registry, new HTTPConnectorProvider());
+
+		// 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);
+		}
+
+		return 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, VABMultiSubmodelProvider 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.getModelPropertyValue("/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.getModelPropertyValue("/aas");
+		return AssetAdministrationShell.createAsFacade(aasMap);
+	}
+
+	@Override
+	public void createAAS(AssetAdministrationShell aas) {
+		MongoDBAASAPI aasApi = new MongoDBAASAPI(config, aas.getIdentification().getId());
+		aasApi.setAAS(aas);
+		AASModelProvider provider = new AASModelProvider(aasApi);
+		aasProviderMap.put(aas.getIdentification().getId(), new VABMultiSubmodelProvider(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 VABMultiSubmodelProvider getProviderForAASId(String aasId) {
+		return aasProviderMap.get(aasId);
+	}
+
+	@Override
+	public IModelProvider getAASProvider(IIdentifier aasId) {
+		VABMultiSubmodelProvider 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..2211d42
--- /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,360 @@
+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.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.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);
+	}
+
+	@Override
+	public ISubmodelElement getSubmodelElement(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.getModelPropertyValue("");
+		return SubmodelElement.createAsFacade((Map<String, Object>) elementVABObj);
+	}
+
+	@Override
+	public void deleteSubmodelElement(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();
+	}
+
+
+	@Override
+	public void addSubmodelElement(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();
+	}
+
+	@Override
+	public void updateSubmodelElement(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).setModelPropertyValue(Property.VALUE, newValue);
+		// Replace db entry
+		Query hasId = query(where(SMIDPATH).is(smId));
+		mongoOps.findAndReplace(hasId, sm, collection);
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public 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.setModelPropertyValue(Property.VALUE, newValue);
+
+		// Replace db entry
+		Query hasId = query(where(SMIDPATH).is(smId));
+		mongoOps.findAndReplace(hasId, sm, collection);
+	}
+
+	@Override
+	public Object getSubmodelElementValue(String idShort) {
+		SubModel sm = (SubModel) getSubmodel();
+		return getElementProvider(sm, idShort).getModelPropertyValue("/value");
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public Object getNestedSubmodelElementValue(List<String> idShorts) {
+		ISubmodelElement lastElement = getNestedSubmodelElement(idShorts);
+		IModelProvider mapProvider = new VABMapProvider((Map<String, Object>) lastElement);
+		return SubmodelElementProvider.getElementProvider(mapProvider).getModelPropertyValue("/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);
+	}
+
+	@Override
+	public 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));
+	}
+
+	@Override
+	public Object invokeOperation(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");
+	}
+
+	@Override
+	public 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);
+	}
+
+	@Override
+	public 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");
+	}
+
+	@Override
+	public 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(List<String> idShorts, 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");
+	}
+}
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..e5b82cc
--- /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,25 @@
+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..82a0083
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/resources/aas.properties
@@ -0,0 +1,5 @@
+aas.backend=InMemory
+aas.source=
+# Example for loading an .aasx file and registering the AAS:
+#registry.path=http://localhost:4000/registry/
+#aas.source=aasx/01_Festo.aasx
\ 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..bd80d1d 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,3 @@
 contextPath=/aasServer
 contextHostname=localhost
-contextPort=4000
\ No newline at end of file
+contextPort=4001
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/src/test/resources/localMongodb.properties b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/resources/mongodb.properties
similarity index 73%
copy from components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/src/test/resources/localMongodb.properties
copy to components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/resources/mongodb.properties
index e4c65b6..30acebe 100644
--- a/components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/src/test/resources/localMongodb.properties
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/resources/mongodb.properties
@@ -9,4 +9,6 @@
 dbuser 							= admin
 dbname 							= admin
 dbconnectionstring              = mongodb://localhost:27017/
-dbcollection              		= registry
\ No newline at end of file
+dbcollectionRegistry       		= registry
+dbcollectionAAS 	      		= assetadministrationshells
+dbcollectionSubmodels       	= submodels
\ 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.AASServer/src/main/resources/xml/aas.xml
similarity index 99%
rename from components/basys.components/basyx.components.docker/basyx.components.xmlAAS/src/main/resources/xml/aas.xml
rename to components/basys.components/basyx.components.docker/basyx.components.AASServer/src/main/resources/xml/aas.xml
index 04a32c8..c84ba35 100644
--- 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.AASServer/src/main/resources/xml/aas.xml
@@ -252,7 +252,7 @@
 						</aas:valueId>
 						<aas:value>qualifierValue</aas:value>
 						<aas:type>qualifierType</aas:type>
-						<aas:valueType>valueType</aas:valueType>
+						<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>
@@ -306,7 +306,7 @@
 									</aas:valueId>
 									<aas:value>qualifierValue</aas:value>
 									<aas:type>qualifierType</aas:type>
-									<aas:valueType>valueType</aas:valueType>
+									<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>
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/AASServerSuite.java b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/AASServerSuite.java
similarity index 93%
rename from components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/basyx/components/AASServer/AASServerSuite.java
rename to components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/AASServerSuite.java
index 10e3826..cf485e6 100644
--- 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/eclipse/basyx/regression/AASServer/AASServerSuite.java
@@ -1,4 +1,4 @@
-package org.basyx.components.AASServer;
+package org.eclipse.basyx.regression.AASServer;
 
 import static org.junit.Assert.assertEquals;
 
@@ -18,7 +18,7 @@
  * 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
+ * @author espen
  *
  */
 public abstract class AASServerSuite {
@@ -45,8 +45,7 @@
 		IIdentifier identifier = new ModelUrn(aasId);
 		shell.setIdentification(identifier);
 		shell.setIdShort("aasIdShort");
-		
-		manager.createAAS(shell, identifier, getURL());
+		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.AASX/src/test/java/org/eclipse/basyx/regression/aasx/AASXSuite.java b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/AASXSuite.java
similarity index 81%
rename from components/basys.components/basyx.components.docker/basyx.components.AASX/src/test/java/org/eclipse/basyx/regression/aasx/AASXSuite.java
rename to components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/AASXSuite.java
index bd2c82e..d04a7cc 100644
--- 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.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/AASXSuite.java
@@ -1,6 +1,7 @@
-package org.eclipse.basyx.regression.aasx;
+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;
@@ -10,7 +11,6 @@
 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;
@@ -21,7 +21,6 @@
 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;
@@ -41,14 +40,14 @@
  * @author schnicke, espen
  *
  */
-public class AASXSuite {
+public abstract 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 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
@@ -93,13 +92,15 @@
 
 	@Test
 	public void testGetSingleModule() throws Exception {
-		checkFile("aasx/Nameplate/marking_rcm.jpg");
+		final String FILE_ENDING = "aasx/Nameplate/marking_rcm.jpg";
+		final String FILE_PATH = rootEndpoint + "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();
+		Collection<ISubmodelElement> values = marking_rcm.getValue().values();
 
 		// navigate to the File element
 		Iterator<ISubmodelElement> iter = values.iterator();
@@ -110,7 +111,7 @@
 				// get value of the file element
 
 				String fileurl = connectedFile.getValue();
-				assertEquals("http://localhost:4000/aasx/docs/marking_rcm.jpg", fileurl);
+				assertTrue(fileurl.endsWith(FILE_ENDING));
 			}
 		}
 	}
@@ -124,6 +125,13 @@
 		Map<String, ISubModel> submodels = aas.getSubModels();
 		logger.info("# Submodels: " + submodels.size());
 		for (ISubModel sm : submodels.values()) {
+			// FIXME: In Identification, there's a file referenced that is not contained in aasx folder. 
+			// Since the current code only works with files in /aasx folder, this will create an error for now
+			// Remove this after this issue is fixed!
+			if (sm.getIdShort().equals("Identification")) {
+				continue;
+			}
+			
 			logger.info("Checking submodel: " + sm.getIdShort());
 			checkElementCollectionFiles(sm.getSubmodelElements().values());
 		}
@@ -137,21 +145,20 @@
 				checkFile(fileUrl);
 			} else if (element instanceof ISubmodelElementCollection) {
 				ISubmodelElementCollection col = (ISubmodelElementCollection) element;
-				checkElementCollectionFiles(col.getValue());
+				checkElementCollectionFiles(col.getSubmodelElements().values());
 			}
 		}
 	}
 
-	private void checkFile(String relativePath) {
+	private void checkFile(String absolutePath) {
 		// 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);
+		WebTarget webTarget = client.target(absolutePath);
+		logger.info("Checking file: " + absolutePath);
+		Invocation.Builder invocationBuilder = webTarget.request();
 		Response response = invocationBuilder.get();
+
 		// validate the response
-		assertEquals(200, response.getStatus());
+		assertEquals("Path check failed: " + absolutePath, 200, response.getStatus());
 	}
 
 	/**
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..f1ad39f
--- /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,33 @@
+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..c52f530
--- /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,60 @@
+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.AASX/src/test/java/org/eclipse/basyx/regression/aasx/TestAASXPackageManager.java b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/TestAASXPackageManager.java
similarity index 93%
rename from components/basys.components/basyx.components.docker/basyx.components.AASX/src/test/java/org/eclipse/basyx/regression/aasx/TestAASXPackageManager.java
rename to components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/TestAASXPackageManager.java
index 89225de..e96614b 100644
--- 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.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/TestAASXPackageManager.java
@@ -1,4 +1,4 @@
-package org.eclipse.basyx.regression.aasx;
+package org.eclipse.basyx.regression.AASServer;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
@@ -6,7 +6,6 @@
 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;
@@ -15,7 +14,7 @@
 import javax.xml.parsers.ParserConfigurationException;
 
 import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
-import org.eclipse.basyx.components.aasx.AASXPackageManager;
+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.reference.IKey;
@@ -23,6 +22,7 @@
 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.submodel.metamodel.map.submodelelement.dataelement.property.valuetypedef.PropertyValueTypeDef;
 import org.eclipse.basyx.support.bundle.AASBundle;
 import org.junit.Before;
 import org.junit.Test;
@@ -202,7 +202,7 @@
 		assertTrue(sele.getModelingKind().name().equalsIgnoreCase("Instance"));
 		Property prop = (Property) sele;
 		assertEquals("Festo AG & Co. KG", prop.get());
-		assertEquals("string", prop.getValueType());
+		assertEquals(PropertyValueTypeDef.String, prop.getValueType());
 
 		// get semantic id
 		IReference semantic = sele.getSemanticId();
@@ -222,7 +222,7 @@
 		assertTrue(sele.getModelingKind().name().equalsIgnoreCase("Instance"));
 		prop = (Property) sele;
 		assertEquals("OVEL Vacuum generator", prop.get());
-		assertEquals("string", prop.getValueType());
+		assertEquals(PropertyValueTypeDef.String, prop.getValueType());
 
 		// get semantic id
 		semantic = sele.getSemanticId();
@@ -251,15 +251,14 @@
 		// get values
 		assertTrue(sele.getModelType().equalsIgnoreCase("SubmodelElementCollection"));
 		SubmodelElementCollection collection = (SubmodelElementCollection) sele;
-		Collection<ISubmodelElement> subelements = collection.getValue();
+		Map<String, ISubmodelElement> smElemMap = collection.getSubmodelElements();
 
-		assertEquals(5, subelements.size());
-		Iterator<ISubmodelElement> iterator = subelements.iterator();
-		Property prop1 = (Property) (iterator.next());
+		assertEquals(5, smElemMap.size());
+		Property prop1 = (Property) smElemMap.get("CountryCode");
 		assertEquals("CountryCode", prop1.getIdShort());
 		assertEquals("DE", prop1.get());
 
-		Property prop2 = (Property) (iterator.next());
+		Property prop2 = (Property) smElemMap.get("Street");
 		assertEquals("Street", prop2.getIdShort());
 		assertEquals("Ruiter Straße 82", prop2.get());
 	}
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..1d0f91e
--- /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,86 @@
+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.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.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();
+		submodel.setIdShort("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/basyx/components/AASServer/TestAASServer.java b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/TestInMemoryAASServer.java
similarity index 65%
rename from components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/basyx/components/AASServer/TestAASServer.java
rename to components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/TestInMemoryAASServer.java
index 758237e..4842f86 100644
--- 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/eclipse/basyx/regression/AASServer/TestInMemoryAASServer.java
@@ -1,10 +1,12 @@
-package org.basyx.components.AASServer;
+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;
 
@@ -14,13 +16,13 @@
  * @author schnicke
  *
  */
-public class TestAASServer extends AASServerSuite {
+public class TestInMemoryAASServer extends AASServerSuite {
 
 	private static AASServerComponent component;
 
 	@Override
 	protected String getURL() {
-		return component.getURL();
+		return component.getURL() + "/shells";
 	}
 
 	@BeforeClass
@@ -28,7 +30,12 @@
 		BaSyxContextConfiguration config = new BaSyxContextConfiguration();
 		config.loadFromResource(BaSyxContextConfiguration.DEFAULT_CONFIG_PATH);
 
-		component = new AASServerComponent(config.getHostname(), config.getPort(), config.getContextPath(), config.getDocBasePath());
+		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/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..3350a9d
--- /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,17 @@
+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..f82fcd7
--- /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,52 @@
+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.aas.configuration.AASServerBackend;
+import org.eclipse.basyx.components.aas.configuration.BaSyxAASServerConfiguration;
+import org.eclipse.basyx.components.aas.mongodb.MongoDBAASAggregator;
+import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
+import org.eclipse.basyx.components.configuration.BaSyxMongoDBConfiguration;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.xml.sax.SAXException;
+
+/**
+ * Tests the component using the test suite
+ * 
+ * @author espen
+ *
+ */
+public class TestMongoDBServer extends AASServerSuite {
+
+	private static AASServerComponent component;
+
+	@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);
+		BaSyxMongoDBConfiguration mongoDBConfig = new BaSyxMongoDBConfiguration();
+		BaSyxAASServerConfiguration aasConfig = new BaSyxAASServerConfiguration(AASServerBackend.MONGODB, "");
+
+		// Start component
+		component = new AASServerComponent(contextConfig, aasConfig, mongoDBConfig);
+		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/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..9326fb9
--- /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,114 @@
+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.ConnectorProvider;
+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 ConnectorProvider() {
+				@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
+				.getModelPropertyValue("/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..e6da6c3
--- /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,112 @@
+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.IAASRegistryService;
+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.IConnectorProvider;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
+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 IAASRegistryService 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
+		IConnectorProvider connectorProvider = new HTTPConnectorProvider();
+		manager = new ConnectedAssetAdministrationShellManager(registry, connectorProvider);
+	}
+
+
+	@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..077762c
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/resources/.env
@@ -0,0 +1,5 @@
+BASYX_HOST_PORT=8082
+BASYX_CONTAINER_PORT=4001
+BASYX_IMAGE_NAME=basys/aas-server
+BASYX_CONTAINER_NAME=aas
+BASYX_IMAGE_TAG=0.1.0-SNAPSHOT
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/src/main/resources/dockerMongodb.properties b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/resources/dockerMongodb.properties
similarity index 73%
copy from components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/src/main/resources/dockerMongodb.properties
copy to components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/resources/dockerMongodb.properties
index 5fc816a..f91b7d4 100644
--- a/components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/src/main/resources/dockerMongodb.properties
+++ b/components/basys.components/basyx.components.docker/basyx.components.AASServer/src/test/resources/dockerMongodb.properties
@@ -9,4 +9,6 @@
 dbuser 							= admin
 dbname 							= admin
 dbconnectionstring              = mongodb://mongodb:27017/
-dbcollection              		= registry
\ No newline at end of file
+dbcollectionRegistry       		= registry
+dbcollectionAAS 	      		= assetadministrationshells
+dbcollectionSubmodels       	= submodels
\ No newline at end of file
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/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/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/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.mongodbregistry/Dockerfile b/components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/Dockerfile
deleted file mode 100644
index 3628774..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/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.mongodbregistry/src/main/java/org/eclipse/basyx/components/MongoDBRegistryComponent.java b/components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/src/main/java/org/eclipse/basyx/components/MongoDBRegistryComponent.java
deleted file mode 100644
index 4b62cf2..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/src/main/java/org/eclipse/basyx/components/MongoDBRegistryComponent.java
+++ /dev/null
@@ -1,62 +0,0 @@
-package org.eclipse.basyx.components;
-
-import org.eclipse.basyx.components.mongodbregistry.BaSyxMongoDBConfiguration;
-import org.eclipse.basyx.components.servlet.MongoDBRegistryServlet;
-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 a MongoDB database.
- * 
- * @author espen
- */
-public class MongoDBRegistryComponent {
-	private static Logger logger = LoggerFactory.getLogger(MongoDBRegistryComponent.class);
-
-	// BaSyx context information
-	private String hostName;
-	private int port;
-	private String path;
-	private String docBasePath;
-	private BaSyxMongoDBConfiguration config;
-
-	// The server with the servlet that will be created
-	private AASHTTPServer server;
-
-	public MongoDBRegistryComponent(String hostName, int port, String path, String docBasePath, String dbPropertyPath) {
-		// Load configuration
-		this.config = new BaSyxMongoDBConfiguration();
-		this.config.loadFromResource(dbPropertyPath);
-		// Sets the server context
-		this.hostName = hostName;
-		this.port = port;
-		this.path = path;
-		this.docBasePath = docBasePath;
-	}
-
-	public MongoDBRegistryComponent(String hostName, int port, String path, String docBasePath,
-			BaSyxMongoDBConfiguration dbConfig) {
-		this.config = dbConfig;
-		// 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 MongoDBRegistryServlet(config));
-		server = new AASHTTPServer(context);
-
-		logger.info("Start the server...");
-		server.start();
-	}
-}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/src/main/java/org/eclipse/basyx/components/executable/MongoDBRegistryExecutable.java b/components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/src/main/java/org/eclipse/basyx/components/executable/MongoDBRegistryExecutable.java
deleted file mode 100644
index cbdd94e..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/src/main/java/org/eclipse/basyx/components/executable/MongoDBRegistryExecutable.java
+++ /dev/null
@@ -1,49 +0,0 @@
-package org.eclipse.basyx.components.executable;
-
-import org.eclipse.basyx.components.MongoDBRegistryComponent;
-import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
-import org.eclipse.basyx.components.mongodbregistry.BaSyxMongoDBConfiguration;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * A registry servlet based on a MongoDB database. The servlet therefore provides an implementation
- * for the IAASRegistryService interface with a permanent storage solution. The properties for the
- * MongoDB connection will be read from executables.properties in the resource folder.
- * 
- * @author espen
- */
-public class MongoDBRegistryExecutable {
-	private static Logger logger = LoggerFactory.getLogger(MongoDBRegistryExecutable.class);
-
-	private MongoDBRegistryExecutable() {
-	}
-
-	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);
-		}
-
-		MongoDBRegistryComponent component;
-		BaSyxMongoDBConfiguration dbConfig = new BaSyxMongoDBConfiguration();
-		if (args.length > 1 && args[1] instanceof String) {
-			// file path available? => load mongodb configs from file
-			dbConfig.loadFromFile(args[1]);
-			component = new MongoDBRegistryComponent(config.getHostname(), config.getPort(), config.getContextPath(),
-					config.getDocBasePath(), dbConfig);
-		} else {
-			component = new MongoDBRegistryComponent(config.getHostname(), config.getPort(), config.getContextPath(),
-					config.getDocBasePath(), "dockerMongodb.properties");
-		}
-
-		component.startComponent();
-	}
-}
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/src/main/java/org/eclipse/basyx/components/mongodbregistry/BaSyxMongoDBConfiguration.java b/components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/src/main/java/org/eclipse/basyx/components/mongodbregistry/BaSyxMongoDBConfiguration.java
deleted file mode 100644
index 278ff22..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/src/main/java/org/eclipse/basyx/components/mongodbregistry/BaSyxMongoDBConfiguration.java
+++ /dev/null
@@ -1,62 +0,0 @@
-package org.eclipse.basyx.components.mongodbregistry;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.eclipse.basyx.components.configuration.BaSyxConfiguration;
-
-/**
- * Represents a BaSyx configuration for a MongoDB connection.
- * 
- * @author espen
- *
- */
-public class BaSyxMongoDBConfiguration extends BaSyxConfiguration {
-	// Default BaSyx SQL configuration
-	private static final String DEFAULT_USER = "admin";
-	private static final String DEFAULT_CONNECTIONURL = "mongodb://127.0.0.1:27017/";
-	private static final String DEFAULT_DATABASE = "admin";
-	private static final String DEFAULT_COLLECTION = "basyx";
-
-	private static final String USER = "dbuser";
-	private static final String DATABASE = "dbname";
-	private static final String CONNECTIONURL = "dbconnectionstring";
-	private static final String COLLECTION = "dbcollection";
-
-	// The default path for the context properties file
-	public static final String DEFAULT_CONFIG_PATH = "mongodb.properties";
-
-	public static Map<String, String> getDefaultProperties() {
-		Map<String, String> defaultProps = new HashMap<>();
-		defaultProps.put(USER, DEFAULT_USER);
-		defaultProps.put(CONNECTIONURL, DEFAULT_CONNECTIONURL);
-		defaultProps.put(DATABASE, DEFAULT_DATABASE);
-		defaultProps.put(COLLECTION, DEFAULT_COLLECTION);
-
-		return defaultProps;
-	}
-
-	public BaSyxMongoDBConfiguration(Map<String, String> values) {
-		super(values);
-	}
-
-	public BaSyxMongoDBConfiguration() {
-		super(getDefaultProperties());
-	}
-
-	public String getUser() {
-		return getProperty(USER);
-	}
-
-	public String getDatabase() {
-		return getProperty(DATABASE);
-	}
-
-	public String getConnectionUrl() {
-		return getProperty(CONNECTIONURL);
-	}
-
-	public String getCollection() {
-		return getProperty(COLLECTION);
-	}
-}
diff --git a/components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/src/main/resources/logback.xml b/components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/src/main/resources/logback.xml
deleted file mode 100644
index 86341d6..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/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.mongodbregistry/src/test/resources/.env b/components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/src/test/resources/.env
deleted file mode 100644
index aafb522..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/src/test/resources/.env
+++ /dev/null
@@ -1,5 +0,0 @@
-BASYX_HOST_PORT=8082
-BASYX_CONTAINER_PORT=4000
-BASYX_IMAGE_NAME=basys/registry-mongodb
-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.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.mongodbregistry/pom.xml b/components/basys.components/basyx.components.docker/basyx.components.registry/pom.xml
similarity index 90%
rename from components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/pom.xml
rename to components/basys.components/basyx.components.docker/basyx.components.registry/pom.xml
index 2f97491..656cc93 100644
--- a/components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/pom.xml
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/pom.xml
@@ -6,14 +6,14 @@
 	<parent>
 		<groupId>org.eclipse.basyx</groupId>
 		<artifactId>basyx.components.docker</artifactId>
-		<version>0.0.1-SNAPSHOT</version>
+		<version>0.1.0-SNAPSHOT</version>
     </parent>
 	
-	<artifactId>basyx.components.mongodbregistry</artifactId>
-	<name>BaSyx MongoDB Registry</name>
+	<artifactId>basyx.components.registry</artifactId>
+	<name>BaSyx Registry</name>
 	
 	<properties>
-		<basyx.components.executable>org.eclipse.basyx.components.executable.MongoDBRegistryExecutable</basyx.components.executable>
+		<basyx.components.executable>org.eclipse.basyx.components.registry.executable.RegistryExecutable</basyx.components.executable>
 	</properties>
 	
 	<packaging>jar</packaging>
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..f939dc5
--- /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,181 @@
+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.AASHTTPServer;
+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 AASHTTPServer 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 AASHTTPServer(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..1805538
--- /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,58 @@
+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 {
+	// 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 loadFromDefaultSource() {
+		loadFileOrDefaultResource(DEFAULT_FILE_KEY, DEFAULT_CONFIG_PATH);
+	}
+
+	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..c0850c0
--- /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,53 @@
+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..0143dda
--- /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,29 @@
+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();
+	}
+}
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/src/main/java/org/eclipse/basyx/components/mongodbregistry/MongoDBRegistryHandler.java b/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/mongodb/MongoDBRegistryHandler.java
similarity index 94%
rename from components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/src/main/java/org/eclipse/basyx/components/mongodbregistry/MongoDBRegistryHandler.java
rename to components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/mongodb/MongoDBRegistryHandler.java
index 3d1830a..50357db 100644
--- a/components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/src/main/java/org/eclipse/basyx/components/mongodbregistry/MongoDBRegistryHandler.java
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/mongodb/MongoDBRegistryHandler.java
@@ -1,4 +1,4 @@
-package org.eclipse.basyx.components.mongodbregistry;
+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;
@@ -7,6 +7,7 @@
 
 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;
@@ -61,7 +62,7 @@
 		this.config = config;
 		MongoClient client = MongoClients.create(config.getConnectionUrl());
 		this.mongoOps = new MongoTemplate(client, config.getDatabase());
-		this.collection = config.getCollection();
+		this.collection = config.getRegistryCollection();
 	}
 
 	@Override
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.registry/src/main/java/org/eclipse/basyx/components/registry/servlet/InMemoryRegistryServlet.java
similarity index 93%
rename from components/basys.components/basyx.components.docker/basyx.components.simple/src/main/java/org/eclipse/basyx/components/servlets/InMemoryRegistryServlet.java
rename to components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/servlet/InMemoryRegistryServlet.java
index 933577b..493d5c1 100644
--- 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.registry/src/main/java/org/eclipse/basyx/components/registry/servlet/InMemoryRegistryServlet.java
@@ -1,4 +1,4 @@
-package org.eclipse.basyx.components.servlets;
+package org.eclipse.basyx.components.registry.servlet;
 
 import org.eclipse.basyx.aas.registration.memory.InMemoryRegistry;
 import org.eclipse.basyx.aas.registration.restapi.DirectoryModelProvider;
diff --git a/components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/src/main/java/org/eclipse/basyx/components/servlet/MongoDBRegistryServlet.java b/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/servlet/MongoDBRegistryServlet.java
similarity index 81%
rename from components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/src/main/java/org/eclipse/basyx/components/servlet/MongoDBRegistryServlet.java
rename to components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/servlet/MongoDBRegistryServlet.java
index 838c533..21d5291 100644
--- a/components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/src/main/java/org/eclipse/basyx/components/servlet/MongoDBRegistryServlet.java
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/servlet/MongoDBRegistryServlet.java
@@ -1,9 +1,9 @@
-package org.eclipse.basyx.components.servlet;
+package org.eclipse.basyx.components.registry.servlet;
 
 import org.eclipse.basyx.aas.registration.memory.AASRegistry;
 import org.eclipse.basyx.aas.registration.restapi.DirectoryModelProvider;
-import org.eclipse.basyx.components.mongodbregistry.BaSyxMongoDBConfiguration;
-import org.eclipse.basyx.components.mongodbregistry.MongoDBRegistryHandler;
+import org.eclipse.basyx.components.configuration.BaSyxMongoDBConfiguration;
+import org.eclipse.basyx.components.registry.mongodb.MongoDBRegistryHandler;
 import org.eclipse.basyx.vab.protocol.http.server.VABHTTPInterface;
 
 /**
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.registry/src/main/java/org/eclipse/basyx/components/registry/servlet/SQLRegistryServlet.java
similarity index 69%
rename from components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/main/java/org/eclipse/basyx/components/servlet/SQLRegistryServlet.java
rename to components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/servlet/SQLRegistryServlet.java
index ff69ac7..37e011f 100644
--- 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.registry/src/main/java/org/eclipse/basyx/components/registry/servlet/SQLRegistryServlet.java
@@ -1,7 +1,8 @@
-package org.eclipse.basyx.components.servlet;
+package org.eclipse.basyx.components.registry.servlet;
 
 import org.eclipse.basyx.aas.registration.restapi.DirectoryModelProvider;
-import org.eclipse.basyx.components.sqlregistry.SQLRegistry;
+import org.eclipse.basyx.components.configuration.BaSyxSQLConfiguration;
+import org.eclipse.basyx.components.registry.sql.SQLRegistry;
 import org.eclipse.basyx.vab.protocol.http.server.VABHTTPInterface;
 
 /**
@@ -21,7 +22,7 @@
 		super(new DirectoryModelProvider(new SQLRegistry()));
 	}
 
-	public SQLRegistryServlet(String customConfigFilePath) {
-		super(new DirectoryModelProvider(new SQLRegistry(customConfigFilePath)));
+	public SQLRegistryServlet(BaSyxSQLConfiguration sqlConfig) {
+		super(new DirectoryModelProvider(new SQLRegistry(sqlConfig)));
 	}
 }
\ 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.registry/src/main/java/org/eclipse/basyx/components/registry/sql/AASDescriptorMap.java
similarity index 97%
rename from components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/main/java/org/eclipse/basyx/components/sqlregistry/AASDescriptorMap.java
rename to components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/sql/AASDescriptorMap.java
index d754f4c..5337ec8 100644
--- 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.registry/src/main/java/org/eclipse/basyx/components/registry/sql/AASDescriptorMap.java
@@ -1,4 +1,4 @@
-package org.eclipse.basyx.components.sqlregistry;
+package org.eclipse.basyx.components.registry.sql;
 
 import java.util.Collection;
 import java.util.Map;
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.registry/src/main/java/org/eclipse/basyx/components/registry/sql/SQLRegistry.java
similarity index 71%
rename from components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/main/java/org/eclipse/basyx/components/sqlregistry/SQLRegistry.java
rename to components/basys.components/basyx.components.docker/basyx.components.registry/src/main/java/org/eclipse/basyx/components/registry/sql/SQLRegistry.java
index 7effeeb..cbb16af 100644
--- 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.registry/src/main/java/org/eclipse/basyx/components/registry/sql/SQLRegistry.java
@@ -1,4 +1,4 @@
-package org.eclipse.basyx.components.sqlregistry;
+package org.eclipse.basyx.components.registry.sql;
 
 import java.io.FileNotFoundException;
 import java.io.IOException;
@@ -18,22 +18,11 @@
  *
  */
 public class SQLRegistry extends AASRegistry {
-	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 MapRegistryHandler(new AASDescriptorMap(createRootMap(configFilePath))));
-	}
-
-	/**
-	 * Constructor using default sql connections
+	 * Constructor using default sql connection
 	 */
 	public SQLRegistry() {
-		this(DEFAULT_SQL_CONFIG_PATH);
+		super(new MapRegistryHandler(new AASDescriptorMap(createRootMap(new BaSyxSQLConfiguration()))));
 	}
 
 	/**
@@ -43,12 +32,6 @@
 		super(new MapRegistryHandler(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();
@@ -71,7 +54,7 @@
 		String user = config.getUser();
 		String pass = config.getPass();
 		String qryPfx = config.getPrefix();
-		String qDrvCls = config.getDrv();
+		String qDrvCls = config.getDriver();
 
 		// 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.registry/src/main/resources/context.properties
similarity index 100%
rename from components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/main/resources/context.properties
rename to components/basys.components/basyx.components.docker/basyx.components.registry/src/main/resources/context.properties
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.mongodbregistry/src/test/resources/localMongodb.properties b/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/resources/mongodb.properties
similarity index 90%
rename from components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/src/test/resources/localMongodb.properties
rename to components/basys.components/basyx.components.docker/basyx.components.registry/src/main/resources/mongodb.properties
index e4c65b6..279374c 100644
--- a/components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/src/test/resources/localMongodb.properties
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/resources/mongodb.properties
@@ -9,4 +9,4 @@
 dbuser 							= admin
 dbname 							= admin
 dbconnectionstring              = mongodb://localhost:27017/
-dbcollection              		= registry
\ No newline at end of file
+dbcollectionRegistry       		= registry
\ 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..f50cc25
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/resources/registry.properties
@@ -0,0 +1 @@
+registry.backend=InMemory
\ No newline at end of file
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..638f973
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/src/main/resources/sql.properties
@@ -0,0 +1,9 @@
+# ##############################################################
+# 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.mongodbregistry/src/test/java/org/eclipse/basyx/regression/registry/ITMongoDBRegistry.java b/components/basys.components/basyx.components.docker/basyx.components.registry/src/test/java/org/eclipse/basyx/regression/registry/ITRegistry.java
similarity index 87%
rename from components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/src/test/java/org/eclipse/basyx/regression/registry/ITMongoDBRegistry.java
rename to components/basys.components/basyx.components.docker/basyx.components.registry/src/test/java/org/eclipse/basyx/regression/registry/ITRegistry.java
index 1c1e320..350d4a9 100644
--- a/components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/src/test/java/org/eclipse/basyx/regression/registry/ITMongoDBRegistry.java
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/src/test/java/org/eclipse/basyx/regression/registry/ITRegistry.java
@@ -9,8 +9,8 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class ITMongoDBRegistry extends TestRegistryProviderSuite {
-	private static Logger logger = LoggerFactory.getLogger(ITMongoDBRegistry.class);
+public class ITRegistry extends TestRegistryProviderSuite {
+	private static Logger logger = LoggerFactory.getLogger(ITRegistry.class);
 
 	private static String registryUrl;
 
@@ -34,7 +34,6 @@
 
 	@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.registry/src/test/java/org/eclipse/basyx/regression/registry/ITRegistryRaw.java
similarity index 98%
rename from components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/test/java/org/eclipse/basyx/regression/registry/ITSQLRegistryRaw.java
rename to components/basys.components/basyx.components.docker/basyx.components.registry/src/test/java/org/eclipse/basyx/regression/registry/ITRegistryRaw.java
index 2c5ed04..c06566c 100644
--- 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.registry/src/test/java/org/eclipse/basyx/regression/registry/ITRegistryRaw.java
@@ -32,8 +32,8 @@
  * @author espen
  *
  */
-public class ITSQLRegistryRaw {
-	private static Logger logger = LoggerFactory.getLogger(ITSQLRegistry.class);
+public class ITRegistryRaw {
+	private static Logger logger = LoggerFactory.getLogger(ITRegistryRaw.class);
 
 	/**
 	 * Serialization
diff --git a/components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/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
similarity index 76%
rename from components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/src/test/java/org/eclipse/basyx/regression/registry/TestMongoDBRegistry.java
rename to components/basys.components/basyx.components.docker/basyx.components.registry/src/test/java/org/eclipse/basyx/regression/registry/TestMongoDBRegistry.java
index d314ada..0ff2b59 100644
--- a/components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/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
@@ -2,7 +2,7 @@
 
 import org.eclipse.basyx.aas.registration.api.IAASRegistryService;
 import org.eclipse.basyx.aas.registration.memory.AASRegistry;
-import org.eclipse.basyx.components.mongodbregistry.MongoDBRegistryHandler;
+import org.eclipse.basyx.components.registry.mongodb.MongoDBRegistryHandler;
 import org.eclipse.basyx.testsuite.regression.aas.registration.TestRegistryProviderSuite;
 
 /**
@@ -15,6 +15,6 @@
 
 	@Override
 	protected IAASRegistryService getRegistryService() {
-		return new AASRegistry(new MongoDBRegistryHandler("localMongodb.properties"));
+		return new AASRegistry(new MongoDBRegistryHandler("mongodb.properties"));
 	}
 }
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.registry/src/test/java/org/eclipse/basyx/regression/registry/TestSQLRegistryProvider.java
similarity index 61%
rename from components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/test/java/org/eclipse/basyx/regression/registry/TestSQLRegistryProvider.java
rename to components/basys.components/basyx.components.docker/basyx.components.registry/src/test/java/org/eclipse/basyx/regression/registry/TestSQLRegistryProvider.java
index b1e8613..79fc363 100644
--- 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.registry/src/test/java/org/eclipse/basyx/regression/registry/TestSQLRegistryProvider.java
@@ -1,7 +1,8 @@
 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.components.configuration.BaSyxSQLConfiguration;
+import org.eclipse.basyx.components.registry.sql.SQLRegistry;
 import org.eclipse.basyx.testsuite.regression.aas.registration.TestRegistryProviderSuite;
 
 /**
@@ -14,6 +15,8 @@
 
 	@Override
 	protected IAASRegistryService getRegistryService() {
-		return new SQLRegistry("localRegistry.properties");
+		BaSyxSQLConfiguration sqlConfig = new BaSyxSQLConfiguration();
+		sqlConfig.loadFromResource("sql.properties");
+		return new SQLRegistry(sqlConfig);
 	}
 }
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..11c83fa
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/src/test/resources/.env
@@ -0,0 +1,5 @@
+BASYX_HOST_PORT=8082
+BASYX_CONTAINER_PORT=4000
+BASYX_IMAGE_NAME=basyx/registry
+BASYX_CONTAINER_NAME=registry
+BASYX_IMAGE_TAG=0.1.0-SNAPSHOT
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/src/main/resources/dockerMongodb.properties b/components/basys.components/basyx.components.docker/basyx.components.registry/src/test/resources/dockerMongodb.properties
similarity index 90%
rename from components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/src/main/resources/dockerMongodb.properties
rename to components/basys.components/basyx.components.docker/basyx.components.registry/src/test/resources/dockerMongodb.properties
index 5fc816a..3a0b8fe 100644
--- a/components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/src/main/resources/dockerMongodb.properties
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/src/test/resources/dockerMongodb.properties
@@ -9,4 +9,4 @@
 dbuser 							= admin
 dbname 							= admin
 dbconnectionstring              = mongodb://mongodb:27017/
-dbcollection              		= registry
\ No newline at end of file
+dbcollectionRegistry       		= registry
\ 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..f96fb32
--- /dev/null
+++ b/components/basys.components/basyx.components.docker/basyx.components.registry/src/test/resources/dockerSQL.properties
@@ -0,0 +1,9 @@
+# ##############################################################
+# 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.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/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/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 faf7620..0000000
--- a/components/basys.components/basyx.components.docker/basyx.components.sqlregistry/src/test/java/org/eclipse/basyx/regression/registry/ITSQLRegistry.java
+++ /dev/null
@@ -1,40 +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();
-		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/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/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..f9b0d31 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>0.1.0-SNAPSHOT</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>
diff --git a/components/basys.components/basyx.components.lib/pom.xml b/components/basys.components/basyx.components.lib/pom.xml
index f34dbff..41b0fdd 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>0.1.0-SNAPSHOT</version>
     </parent>
 	
 	<artifactId>basyx.components.lib</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..7f8aacb
--- /dev/null
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/IComponent.java
@@ -0,0 +1,20 @@
+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/configuration/BaSyxConfiguration.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/BaSyxConfiguration.java
index 6ad9aba..39b6a8d 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
@@ -53,6 +53,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
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..ca8a966 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
@@ -3,8 +3,7 @@
 import java.util.HashMap;
 import java.util.Map;
 
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.eclipse.basyx.vab.protocol.http.server.BaSyxContext;
 
 /**
  * Represents a BaSyx http servlet configuration for a BaSyxContext,
@@ -14,58 +13,119 @@
  *
  */
 public class BaSyxContextConfiguration extends BaSyxConfiguration {
-	
-	/**
-	 * Initiates a logger using the current class
-	 */
-	private static final Logger logger = LoggerFactory.getLogger(BaSyxContextConfiguration.class);
-	
 	// Default BaSyx Context configuration
 	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 loadFromDefaultSource() {
+		loadFileOrDefaultResource(DEFAULT_FILE_KEY, DEFAULT_CONFIG_PATH);
+	}
+
+	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, 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() {
+		return "http://" + getHostname() + ":" + getPort() + "/" + getContextPath();
+	}
 }
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..cd52038 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
@@ -11,19 +11,22 @@
  */
 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";
+	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";
 
-	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";
+	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 +37,69 @@
 		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 loadFromDefaultSource() {
+		loadFileOrDefaultResource(DEFAULT_FILE_KEY, DEFAULT_CONFIG_PATH);
+	}
+
 	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..5ab9ef5
--- /dev/null
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/BaSyxMongoDBConfiguration.java
@@ -0,0 +1,168 @@
+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 {
+	// Default BaSyx SQL configuration
+	public static final String DEFAULT_USER = "admin";
+	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 USER = "dbuser";
+	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(USER, DEFAULT_USER);
+		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 user               The username for the mongodb
+	 * @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 user, String connectionUrl, String database, String registryCollection,
+			String aasCollection, String submodelCollection) {
+		this();
+		setUser(user);
+		setConnectionUrl(connectionUrl);
+		setDatabase(database);
+		setRegistryCollection(registryCollection);
+		setAASCollection(aasCollection);
+		setSubmodelCollection(submodelCollection);
+	}
+
+	/**
+	 * Constructor with initial configuration (without registry collection)
+	 * 
+	 * @param user               The username for the mongodb
+	 * @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 user, String connectionUrl, String database, String aasCollection,
+			String submodelCollection) {
+		this();
+		setUser(user);
+		setConnectionUrl(connectionUrl);
+		setDatabase(database);
+		setAASCollection(aasCollection);
+		setSubmodelCollection(submodelCollection);
+	}
+
+	/**
+	 * Constructor with initial configuration (without aas collection)
+	 * 
+	 * @param user               The username for the mongodb
+	 * @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 user, String connectionUrl, String database, String registryCollection) {
+		this();
+		setUser(user);
+		setConnectionUrl(connectionUrl);
+		setDatabase(database);
+		setRegistryCollection(registryCollection);
+	}
+
+	public void loadFromDefaultSource() {
+		loadFileOrDefaultResource(DEFAULT_FILE_KEY, DEFAULT_CONFIG_PATH);
+	}
+
+	public String getUser() {
+		return getProperty(USER);
+	}
+
+	public void setUser(String user) {
+		setProperty(USER, user);
+	}
+
+	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/BaSyxSQLConfiguration.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/configuration/BaSyxSQLConfiguration.java
index 1b31a36..86e1295 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
@@ -11,57 +11,108 @@
  */
 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:";
+	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:";
 
-	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";
+	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 loadFromDefaultSource() {
+		loadFileOrDefaultResource(DEFAULT_FILE_KEY, DEFAULT_CONFIG_PATH);
+	}
+
 	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/devicemanager/DeviceManagerComponent.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/devicemanager/DeviceManagerComponent.java
index 4695058..f707f7b 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,6 @@
 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 +78,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");
 	}
 	
 	/**
@@ -90,7 +91,7 @@
 	 */
 	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/provider/BaseConfiguredProvider.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/provider/BaseConfiguredProvider.java
index ca5da6d..8c0220e 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
@@ -21,7 +21,7 @@
 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.MultiSubmodelElementProvider;
 import org.eclipse.basyx.submodel.restapi.vab.VABSubmodelAPI;
 import org.eclipse.basyx.vab.modelprovider.map.VABMapProvider;
 import org.slf4j.Logger;
@@ -96,7 +96,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));
 	}
 
 	/**
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
index 3d7d21a..08cf893 100644
--- 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
@@ -70,7 +70,7 @@
 				throw new RuntimeException("Only instances of SubModel are allowed here");
 			}
 
-			provider.addSubmodel(sm.getIdShort(), new SubModelProvider((SubModel) sm));
+			provider.addSubmodel(new SubModelProvider((SubModel) sm));
 		}
 		return provider;
 	}
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..675742f 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
@@ -4,7 +4,6 @@
 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 +18,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 +67,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 +100,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 +124,7 @@
 	/**
 	 * Operations map
 	 */
-	protected Map<String, Object> operations = new HashMap<String, Object>();
+	protected Map<String, Function<?, ?>> operations = new HashMap<>();
 	
 	
 	/**
@@ -173,8 +152,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 +159,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 +240,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 +258,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 +272,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 +293,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 +446,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 +485,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 +590,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 +608,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..a4e987c 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
@@ -27,14 +27,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 +56,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/support/bundle/AASBundleDescriptorFactory.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/support/bundle/AASBundleDescriptorFactory.java
index 2291fa4..487ed63 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
@@ -24,7 +24,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/AASBundleIntegrator.java b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/support/bundle/AASBundleIntegrator.java
new file mode 100644
index 0000000..8507196
--- /dev/null
+++ b/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/support/bundle/AASBundleIntegrator.java
@@ -0,0 +1,80 @@
+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.submodel.metamodel.api.ISubModel;
+import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
+
+
+/**
+ * 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 AASBundleIntegrator {
+
+	/**
+	 * 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.getModelPropertyValue("/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.setModelPropertyValue("/aas/submodels/" + sm.getIdShort(), sm);
+						objectUploaded = true;
+					} else {
+						throw new RuntimeException("sm Objects in bundles need to be instance of 'SubModel'");
+					}
+				}
+			}
+		}
+		return objectUploaded;
+	}
+	
+}
\ No newline at end of file
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/tools/sql/driver/ISQLDriver.java
similarity index 83%
rename from components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/driver/ISQLDriver.java
rename to components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sql/driver/ISQLDriver.java
index 37095d0..86514e9 100644
--- 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/tools/sql/driver/ISQLDriver.java
@@ -1,4 +1,4 @@
-package org.eclipse.basyx.components.sqlprovider.driver;
+package org.eclipse.basyx.tools.sql.driver;
 
 import java.sql.ResultSet;
 
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/tools/sql/driver/SQLDriver.java
similarity index 96%
rename from components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/driver/SQLDriver.java
rename to components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sql/driver/SQLDriver.java
index 94931ee..0c28589 100644
--- 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/tools/sql/driver/SQLDriver.java
@@ -1,4 +1,4 @@
-package org.eclipse.basyx.components.sqlprovider.driver;
+package org.eclipse.basyx.tools.sql.driver;
 
 import java.sql.Connection;
 import java.sql.ResultSet;
@@ -90,6 +90,7 @@
 	/**
 	 * 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
@@ -126,6 +127,7 @@
 	/**
 	 * Execute a SQL update
 	 */
+	@Override
 	public void sqlUpdate(String updateString) {
 		// Store SQL statement
 		Statement statement              = null;
@@ -159,7 +161,7 @@
 			// Open connection
 			if (connect == null) {
 				openDataSource();
-				connect = ds.getConnection();	
+				connect = ds.getConnection();
 			}
 		} catch (SQLException e) {
 			logger.error("Failed to open sql driver connection", e);
@@ -208,6 +210,7 @@
 			ds.setJdbcUrl(queryPrefix+dbPath);
 			ds.setUsername(userName);
 			ds.setPassword(password);
+			ds.setMaximumPoolSize(5);
 		}
 	}
 	
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/tools/sql/query/DynamicSQLOperation.java
similarity index 95%
rename from components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/query/DynamicSQLOperation.java
rename to components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sql/query/DynamicSQLOperation.java
index 9b8449a..af498a0 100644
--- 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/tools/sql/query/DynamicSQLOperation.java
@@ -1,4 +1,4 @@
-package org.eclipse.basyx.components.sqlprovider.query;
+package org.eclipse.basyx.tools.sql.query;
 
 import java.lang.reflect.InvocationTargetException;
 import java.sql.ResultSet;
@@ -6,10 +6,10 @@
 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.eclipse.basyx.tools.sql.driver.ISQLDriver;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
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/tools/sql/query/DynamicSQLQuery.java
similarity index 96%
rename from components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/query/DynamicSQLQuery.java
rename to components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sql/query/DynamicSQLQuery.java
index 6a5befe..a41f060 100644
--- 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/tools/sql/query/DynamicSQLQuery.java
@@ -1,4 +1,4 @@
-package org.eclipse.basyx.components.sqlprovider.query;
+package org.eclipse.basyx.tools.sql.query;
 
 import java.lang.reflect.InvocationTargetException;
 import java.sql.ResultSet;
@@ -7,10 +7,10 @@
 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;
+import org.eclipse.basyx.tools.sql.driver.ISQLDriver;
 
 
 
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/tools/sql/query/DynamicSQLRunner.java
similarity index 87%
rename from components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/query/DynamicSQLRunner.java
rename to components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sql/query/DynamicSQLRunner.java
index d3a3a88..fe91225 100644
--- 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/tools/sql/query/DynamicSQLRunner.java
@@ -1,11 +1,12 @@
-package org.eclipse.basyx.components.sqlprovider.query;
+package org.eclipse.basyx.tools.sql.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;
+import org.eclipse.basyx.tools.sql.driver.ISQLDriver;
+import org.eclipse.basyx.tools.sql.driver.SQLDriver;
 
 
 
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/tools/sql/query/DynamicSQLUpdate.java
similarity index 92%
rename from components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/query/DynamicSQLUpdate.java
rename to components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/tools/sql/query/DynamicSQLUpdate.java
index 773824b..90334f1 100644
--- 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/tools/sql/query/DynamicSQLUpdate.java
@@ -1,10 +1,10 @@
-package org.eclipse.basyx.components.sqlprovider.query;
+package org.eclipse.basyx.tools.sql.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.eclipse.basyx.tools.sql.driver.ISQLDriver;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
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..7486da0 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
@@ -9,9 +9,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..c869437 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,7 @@
 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..307fd78 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
@@ -10,9 +10,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..852026d 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
@@ -7,9 +7,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..31904cf 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
@@ -6,8 +6,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;
 
 
 
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..a6ff7a2 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
@@ -82,7 +82,7 @@
 		VABMultiSubmodelProvider provider = new VABMultiSubmodelProvider();
 		
 		// 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));
@@ -96,7 +96,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/sqlprovider/SQLInvocationsTest.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sql/SQLInvocationsTest.java
similarity index 97%
rename from components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlprovider/SQLInvocationsTest.java
rename to components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sql/SQLInvocationsTest.java
index f8beb36..9655073 100644
--- 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/sql/SQLInvocationsTest.java
@@ -1,4 +1,4 @@
-package org.eclipse.basyx.regression.sqlprovider;
+package org.eclipse.basyx.regression.sql;
 
 import java.util.Collection;
 import java.util.LinkedList;
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/sql/SQLQueriesTest.java
similarity index 98%
rename from components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sqlprovider/SQLQueriesTest.java
rename to components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/sql/SQLQueriesTest.java
index a06b966..be4cc10 100644
--- 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/sql/SQLQueriesTest.java
@@ -1,4 +1,4 @@
-package org.eclipse.basyx.regression.sqlprovider;
+package org.eclipse.basyx.regression.sql;
 
 import java.util.HashMap;
 import java.util.Map;
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..e84be6f 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
@@ -8,6 +8,7 @@
 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.identifier.Identifier;
 import org.eclipse.basyx.support.bundle.AASBundle;
 import org.eclipse.basyx.support.bundle.AASBundleDescriptorFactory;
 import org.eclipse.basyx.vab.modelprovider.VABPathTools;
@@ -24,7 +25,7 @@
 	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();
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/bundle/TestAASBundleIntegrator.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/bundle/TestAASBundleIntegrator.java
new file mode 100644
index 0000000..527cced
--- /dev/null
+++ b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/bundle/TestAASBundleIntegrator.java
@@ -0,0 +1,164 @@
+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.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.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.AASBundleIntegrator;
+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 TestAASBundleIntegrator {
+
+	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(AASBundleIntegrator.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(AASBundleIntegrator.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(AASBundleIntegrator.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() {
+		IAASRegistryService registry = new InMemoryRegistry();
+		provider = new AASAggregatorProvider(new AASAggregator(registry));
+		aggregator = new AASAggregatorProxy(new VABElementProxy("/shells", provider));
+
+		AASBundle bundle = getTestBundle();
+		bundles.add(bundle);
+
+		assertTrue(AASBundleIntegrator.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.getModelPropertyValue("/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.setModelPropertyValue("/" + 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/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..401557f 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,6 +1,8 @@
 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;
@@ -13,9 +15,9 @@
 		IIdentifier id = new Identifier(IdentifierType.CUSTOM, submodelid);
 		SubModel sm = new SubModel();
 		sm.setIdentification(id.getIdType(), id.getId());
-		AssetAdministrationShell aas = new AssetAdministrationShell();
+		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);
-		aas.put("idshort", aasid);
 
 		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..4aff97c 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
@@ -34,7 +34,7 @@
 		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/submodel/DeviceSubmodelFactory.java b/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/support/processengine/submodel/DeviceSubmodelFactory.java
index 1e1f82d..28a2b53 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
@@ -5,7 +5,9 @@
 import java.util.function.Function;
 
 import org.eclipse.basyx.regression.support.processengine.stubs.ICoilcar;
+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;
 
@@ -45,7 +47,7 @@
 		propList.add(property3);
 		// create the sub-model and add the property and operations to the sub-model
 		SubModel sm = new SubModel(propList, opList);
-
+		sm.setIdentification(new Identifier(IdentifierType.CUSTOM, id + "Custom"));
 		sm.setIdShort(id);
 		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..362385c 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,5 @@
 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 +29,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/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..bcc33bd 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>0.1.0-SNAPSHOT</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>0.1.0-SNAPSHOT</version>
 			</dependency>
 		
 			<!-- BaSyx SDK 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/components/basyx.tck/basyx.tck.AASAggregator/pom.xml b/components/basyx.tck/basyx.tck.AASAggregator/pom.xml
deleted file mode 100644
index 87e9c5c..0000000
--- a/components/basyx.tck/basyx.tck.AASAggregator/pom.xml
+++ /dev/null
@@ -1,57 +0,0 @@
-<?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>0.0.1-SNAPSHOT</version>
-  </parent>
-  
-  <artifactId>basyx.tck.AASAggregator</artifactId>
-  <name>TCK for AASAggregator</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.aggregator.AASAggregatorTestApplication</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.AASAggregator/src/test/java/org/eclipse/basyx/testsuite/regression/aas/aggregator/AASAggregatorSuiteWithDefinedURL.java b/components/basyx.tck/basyx.tck.AASAggregator/src/test/java/org/eclipse/basyx/testsuite/regression/aas/aggregator/AASAggregatorSuiteWithDefinedURL.java
deleted file mode 100644
index 2103c20..0000000
--- a/components/basyx.tck/basyx.tck.AASAggregator/src/test/java/org/eclipse/basyx/testsuite/regression/aas/aggregator/AASAggregatorSuiteWithDefinedURL.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package org.eclipse.basyx.testsuite.regression.aas.aggregator;
-
-import org.eclipse.basyx.aas.aggregator.api.IAASAggregator;
-import org.eclipse.basyx.aas.aggregator.proxy.AASAggregatorProxy;
-
-/**
- * Instantiate a concrete test suite for AASAggregator from the abstract test
- * suite
- * 
- * @author zhangzai
- *
- */
-public class AASAggregatorSuiteWithDefinedURL extends AASAggregatorSuite {
-
-	public static String url;
-
-	@Override
-	protected IAASAggregator getAggregator() {
-		return new AASAggregatorProxy(url);
-	}
-
-}
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..ba6f373
--- /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>0.1.0-SNAPSHOT</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.AASAggregator/src/main/assembly/assembly.xml b/components/basyx.tck/basyx.tck.AASServer/src/main/assembly/assembly.xml
similarity index 100%
rename from components/basyx.tck/basyx.tck.AASAggregator/src/main/assembly/assembly.xml
rename to components/basyx.tck/basyx.tck.AASServer/src/main/assembly/assembly.xml
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..c988c3d
--- /dev/null
+++ b/components/basyx.tck/basyx.tck.AASServer/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/AASAggregatorSuiteWithDefinedURL.java
@@ -0,0 +1,135 @@
+package org.eclipse.basyx.testsuite.regression.aas.metamodel;
+
+import static org.junit.Assert.assertEquals;
+
+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(aasxPath);
+
+		// 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
+		assertEquals(expected, remoteAas.getLocalCopy());
+
+		// 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
+				assertEquals(expectedSm, remote.getLocalCopy());
+			});
+
+		
+		// Delete the AAS
+		aasAggregator.deleteAAS(aasIdentifier);
+
+	}
+
+
+}
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..5a3d310
--- /dev/null
+++ b/components/basyx.tck/basyx.tck.AASServer/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/AASServerTestApplication.java
@@ -0,0 +1,42 @@
+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
index 624a4a5..674f83a 100644
--- a/components/basyx.tck/basyx.tck.registry/pom.xml
+++ b/components/basyx.tck/basyx.tck.registry/pom.xml
@@ -6,7 +6,7 @@
   <parent>
     <groupId>org.eclipse.basyx</groupId>
     <artifactId>basyx.tck</artifactId>
-    <version>0.0.1-SNAPSHOT</version>
+    <version>0.1.0-SNAPSHOT</version>
   </parent>
   
   <artifactId>basyx.tck.registry</artifactId>
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
index 08e05cc..a295ff0 100644
--- 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
@@ -18,4 +18,14 @@
 		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/pom.xml b/components/basyx.tck/pom.xml
index 28205ad..6a0653d 100644
--- a/components/basyx.tck/pom.xml
+++ b/components/basyx.tck/pom.xml
@@ -2,7 +2,7 @@
   <modelVersion>4.0.0</modelVersion>
   <groupId>org.eclipse.basyx</groupId>
   <artifactId>basyx.tck</artifactId>
-  <version>0.0.1-SNAPSHOT</version>
+  <version>0.1.0-SNAPSHOT</version>
   
   
   <packaging>pom</packaging>
@@ -14,7 +14,7 @@
 	
 	<!-- Includes all components in this project as separated modules -->
 	<modules>
-		<module>basyx.tck.AASAggregator</module>
+		<module>basyx.tck.AASServer</module>
 		<module>basyx.tck.registry</module>
 	</modules>
 	
@@ -111,13 +111,13 @@
 			<dependency>
 				<groupId>org.eclipse.basyx</groupId>
 				<artifactId>basyx.sdk</artifactId>
-				<version>0.0.1-SNAPSHOT</version>
+				<version>0.1.0-SNAPSHOT</version>
 			</dependency>
 			<!-- BaSyx SDK 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/examples/basys.examples/pom.xml b/examples/basys.examples/pom.xml
index 9091809..26cdb51 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>0.1.0-SNAPSHOT</version>
   <packaging>jar</packaging>
   <name>BaSyx Examples</name>
   
@@ -271,29 +271,28 @@
 		<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>
+			<artifactId>basyx.components.registry</artifactId>
+			<version>0.1.0-SNAPSHOT</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>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/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..b4b68eb 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,9 +1,18 @@
 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.proxy.AASRegistryProxy;
+import org.eclipse.basyx.components.IComponent;
+import org.eclipse.basyx.components.aas.AASServerComponent;
+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;
@@ -20,7 +29,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 +37,8 @@
 	/**
 	 * The registry used in the manager
 	 */
-	public IAASRegistryService registry;
+	private IAASRegistryService registry;
+	public static String registryPath = "http://localhost:8080/registry";
 	
 	/**
 	 * AASManager used to handle registration and server communication
@@ -52,6 +62,10 @@
 	 */
 	public IIdentifier edgeSmIdentifier = ComponentBuilder.getEdgeSubmodelDescriptor().getIdentifier();
 
+	// Used for shutting down the scenario
+	private List<IComponent> startedComponents = new ArrayList<>();
+	private AASHTTPServer edgeServer;
+
 	/**
 	 * Main method to start the scenario
 	 * 
@@ -66,20 +80,21 @@
 	 */
 	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
@@ -95,6 +110,19 @@
 	}
 	
 	/**
+	 * 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"
 	 * 
@@ -104,8 +132,9 @@
 	 */
 	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();
@@ -118,7 +147,7 @@
 		
 		
 		// Create and start a HTTP server with the context created above
-		AASHTTPServer edgeServer = new AASHTTPServer(context);
+		edgeServer = new AASHTTPServer(context);
 		edgeServer.start();
 	}
 	
@@ -130,12 +159,22 @@
 	 * 
 	 */
 	private void startupCloudServer() {
-		
-		// Create a server at port 8081 with the endpoint "/cloud"
-		AASServerComponent cloudServer = new AASServerComponent("localhost", 8081, "/cloud", "/");
+		// Load the AAS context from a .properties file resource
+		BaSyxContextConfiguration contextConfig = new BaSyxContextConfiguration();
+		contextConfig.loadFromResource("CloudEdgeDeploymentScenarioAASContext.properties");
+
+		// Create a server according to this configuration
+		AASServerComponent cloudServer = new AASServerComponent(contextConfig);
+		cloudServer.setRegistry(registry);
 		
 		// Start the created server
 		cloudServer.startComponent();
+		startedComponents.add(cloudServer);
+	}
+
+	public void stop() {
+		startedComponents.stream().forEach(IComponent::stopComponent);
+		edgeServer.shutdown();
 	}
 
 }
\ No newline at end of file
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..2413878 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
@@ -17,15 +17,15 @@
 
 	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_ENDPOINT = "http://localhost:8082/oven/current_temp/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 DOCUSM_ENDPOINT = "http://localhost:8081/cloud/shells/aasId/aas/submodels/oven_doc/submodel";
 	
 	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 AAS_ENDPOINT = "http://localhost:8081/cloud/shells/aasId/aas";
 	
 	
 	
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..5fec083
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/scenarios/staticdynamic/ExampleDynamicSubmodel.java
@@ -0,0 +1,39 @@
+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.set(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..8bbc6b8
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/scenarios/staticdynamic/StaticDynamicScenario.java
@@ -0,0 +1,170 @@
+package org.eclipse.basyx.examples.scenarios.staticdynamic;
+
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+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.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.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.api.ISubModel;
+import org.eclipse.basyx.submodel.metamodel.map.SubModel;
+import org.eclipse.basyx.support.bundle.AASBundle;
+import org.eclipse.basyx.support.bundle.AASBundleIntegrator;
+import org.eclipse.basyx.vab.exception.provider.ResourceAlreadyExistsException;
+import org.eclipse.basyx.vab.modelprovider.VABPathTools;
+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 IOException, ParserConfigurationException, SAXException, URISyntaxException {
+		new StaticDynamicScenario();
+	}
+
+	public StaticDynamicScenario() throws IOException, ParserConfigurationException, SAXException, URISyntaxException {
+		
+		// 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
+		AASBundleIntegrator.integrate(new AASAggregatorProxy(SERVER_URL), bundles);
+		
+		// Get a RegistryProxy and register all Objects contained in the Bundles
+		AASRegistryProxy proxy = new AASRegistryProxy(REGISTRY_URL);
+		registerBundles(bundles, proxy, 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;
+	}
+	
+	/**
+	 * Registers all AASs and SMs contained in the given Bundles
+	 * 
+	 * @param bundles the Bundles to be registered
+	 * @param registry the registry to be used
+	 * @param serverURL the URL of the server, that holds the AASs/SMs
+	 */
+	private void registerBundles(Set<AASBundle> bundles, IAASRegistryService registry, String serverURL) {
+		for(AASBundle bundle: bundles) {
+			IAssetAdministrationShell aas = bundle.getAAS();
+			String encodedAASId = VABPathTools.encodePathElement(aas.getIdentification().getId());
+			String aasEndpoint = VABPathTools.concatenatePaths(serverURL, AASAggregatorProvider.PREFIX, encodedAASId, "aas");
+			AASDescriptor aasDescriptor = new AASDescriptor(aas, aasEndpoint);
+			try {
+				registry.register(aasDescriptor);
+			} catch(ResourceAlreadyExistsException e) {
+				// Does not matter; AAS was already registered
+			}
+			
+			for(ISubModel sm: bundle.getSubmodels()) {
+				String encodedSMId = VABPathTools.encodePathElement(sm.getIdShort());
+				String smEndpoint = VABPathTools.concatenatePaths(aasEndpoint, "submodels", encodedSMId);
+				SubmodelDescriptor smDescriptor = new SubmodelDescriptor(sm, smEndpoint);
+				try {
+					registry.register(aas.getIdentification(), smDescriptor);
+				} catch(ResourceAlreadyExistsException e) {
+					// Does not matter; SM was already registered
+				}	
+			}
+		}
+	}
+	
+	/**
+	 * 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..62bfe8f
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/aas/AddSubmodelToAAS.java
@@ -0,0 +1,40 @@
+package org.eclipse.basyx.examples.snippets.aas;
+
+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
+ * 
+ * @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/aas/DeleteAAS.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/aas/DeleteAAS.java
new file mode 100644
index 0000000..b79efdf
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/aas/DeleteAAS.java
@@ -0,0 +1,34 @@
+package org.eclipse.basyx.examples.snippets.aas;
+
+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
+ * 
+ * @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/aas/DeleteSubmodelFromAAS.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/aas/DeleteSubmodelFromAAS.java
new file mode 100644
index 0000000..a6e0809
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/aas/DeleteSubmodelFromAAS.java
@@ -0,0 +1,35 @@
+package org.eclipse.basyx.examples.snippets.aas;
+
+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
+ * 
+ * @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);
+	}
+}
\ No newline at end of file
diff --git a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/aas/LookupAAS.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/aas/LookupAAS.java
new file mode 100644
index 0000000..e7ed77c
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/aas/LookupAAS.java
@@ -0,0 +1,31 @@
+package org.eclipse.basyx.examples.snippets.aas;
+
+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/aas/PushAASToServer.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/aas/PushAASToServer.java
new file mode 100644
index 0000000..7a78f28
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/aas/PushAASToServer.java
@@ -0,0 +1,37 @@
+package org.eclipse.basyx.examples.snippets.aas;
+
+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 a AAS to a server
+ * 
+ * @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);
+	}
+}
\ No newline at end of file
diff --git a/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/aas/RegisterAAS.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/aas/RegisterAAS.java
new file mode 100644
index 0000000..02e96b3
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/aas/RegisterAAS.java
@@ -0,0 +1,34 @@
+package org.eclipse.basyx.examples.snippets.aas;
+
+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/aas/RetrieveRemoteAAS.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/aas/RetrieveRemoteAAS.java
new file mode 100644
index 0000000..d50c408
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/aas/RetrieveRemoteAAS.java
@@ -0,0 +1,36 @@
+package org.eclipse.basyx.examples.snippets.aas;
+
+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
+ * 
+ * @author conradi
+ *
+ */
+public class RetrieveRemoteAAS {
+
+	/**
+	 * 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/aas/RetrieveSubmodelFromAAS.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/aas/RetrieveSubmodelFromAAS.java
new file mode 100644
index 0000000..1404875
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/aas/RetrieveSubmodelFromAAS.java
@@ -0,0 +1,38 @@
+package org.eclipse.basyx.examples.snippets.aas;
+
+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 a AAS on a server
+ * 
+ * @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/submodel/AddSubmodelElement.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/submodel/AddSubmodelElement.java
new file mode 100644
index 0000000..a33e08d
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/submodel/AddSubmodelElement.java
@@ -0,0 +1,35 @@
+package org.eclipse.basyx.examples.snippets.submodel;
+
+import org.eclipse.basyx.examples.snippets.aas.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);
+		
+	}
+
+}
\ No newline at end of file
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..8e31408
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/submodel/DeleteSubmodelElement.java
@@ -0,0 +1,31 @@
+package org.eclipse.basyx.examples.snippets.submodel;
+
+import org.eclipse.basyx.examples.snippets.aas.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..74d5774
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/submodel/ExecuteOperation.java
@@ -0,0 +1,45 @@
+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/LookupSubmodel.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/submodel/LookupSubmodel.java
new file mode 100644
index 0000000..1b3e4f4
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/submodel/LookupSubmodel.java
@@ -0,0 +1,32 @@
+package org.eclipse.basyx.examples.snippets.submodel;
+
+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/submodel/RegisterSubmodel.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/submodel/RegisterSubmodel.java
new file mode 100644
index 0000000..6c4a751
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/submodel/RegisterSubmodel.java
@@ -0,0 +1,35 @@
+package org.eclipse.basyx.examples.snippets.submodel;
+
+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 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/RetrieveSubmodelElement.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/submodel/RetrieveSubmodelElement.java
new file mode 100644
index 0000000..cfce36e
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/snippets/submodel/RetrieveSubmodelElement.java
@@ -0,0 +1,34 @@
+package org.eclipse.basyx.examples.snippets.submodel;
+
+import org.eclipse.basyx.examples.snippets.aas.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);
+		
+	}
+}
\ No newline at end of file
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..4260956
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/support/ExampleAASComponent.java
@@ -0,0 +1,53 @@
+package org.eclipse.basyx.examples.support;
+
+import org.eclipse.basyx.aas.registration.api.IAASRegistryService;
+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 IAASRegistryService registry;
+	
+	// Hold a reference to the server to be able to shut it down
+	private AASServerComponent aasServer = null;
+	
+	
+	public ExampleAASComponent(int port, IAASRegistryService 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..7db04ec
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/support/ExampleComponentBuilder.java
@@ -0,0 +1,75 @@
+package org.eclipse.basyx.examples.support;
+
+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.SubmodelElementCollection;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
+
+/**
+ * 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();
+		submodel.setIdShort(idShort);
+		submodel.setIdentification(IdentifierType.CUSTOM, id);
+		
+		// Add a Property to the Submodel
+		Property property = new Property();
+		property.setIdShort(PROPERTY_ID);
+		property.setValue(PROPERTY_VALUE);
+		submodel.addSubModelElement(property);
+				
+		// Add a SubmodelElementCollection
+		SubmodelElementCollection collection = new SubmodelElementCollection();
+		collection.setIdShort(COLLECTION_ID);
+		
+		// Add a Property to the SubmodelElementCollection
+		Property property2 = new Property();
+		property2.setIdShort(COLLECTION_PROPERTY_ID);
+		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) {
+		AssetAdministrationShell aas = new AssetAdministrationShell();
+		aas.setIdShort(idShort);
+		
+		aas.setIdentification(IdentifierType.CUSTOM, id);
+		
+		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..6f6e8a5
--- /dev/null
+++ b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/support/ExampleRegistryComponent.java
@@ -0,0 +1,53 @@
+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/ExamplesPreconfiguredDirectory.java b/examples/basys.examples/src/main/java/org/eclipse/basyx/examples/support/directory/ExamplesPreconfiguredDirectory.java
index 3dd8b66..8f18dce 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
@@ -20,6 +20,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..1201930
--- /dev/null
+++ b/examples/basys.examples/src/main/resources/CloudEdgeDeploymentScenarioAASContext.properties
@@ -0,0 +1,3 @@
+contextPath=/cloud
+contextHostname=localhost
+contextPort=8081
\ No newline at end of file
diff --git a/components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/src/main/resources/context.properties b/examples/basys.examples/src/main/resources/RegistryContext.properties
similarity index 100%
rename from components/basys.components/basyx.components.docker/basyx.components.mongodbregistry/src/main/resources/context.properties
rename to examples/basys.examples/src/main/resources/RegistryContext.properties
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..cb0bbd5
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/contexts/BaSyxExamplesContext.java
@@ -0,0 +1,44 @@
+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..e50e968 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
@@ -16,14 +16,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/mockup/application/ReceiveDeviceDashboardStatusApplication.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/mockup/application/ReceiveDeviceDashboardStatusApplication.java
index 303dc1c..c236b90 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
@@ -7,8 +7,9 @@
 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;
@@ -34,7 +35,7 @@
 	 */
 	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()));
@@ -69,7 +70,7 @@
 	public String getDeviceStatus() {
 		// Read the status property
 		Map<String, Object> property = (Map<String, Object>) aasServerConnection
-				.getModelPropertyValue(SubmodelElementProvider.PROPERTIES + "/status");
+				.getModelPropertyValue(MultiSubmodelElementProvider.ELEMENTS + "/status");
 		// Return the value of the property
 		return property.get("value").toString();
 	}
@@ -82,7 +83,7 @@
 	public int getDeviceInvocationCounter() {
 		// Read the invocation counter for device default service
 		Map<String, Object> property = (Map<String, Object>) aasServerConnection
-				.getModelPropertyValue(SubmodelElementProvider.PROPERTIES + "/invocations");
+				.getModelPropertyValue(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..0c20f1c 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
@@ -7,8 +7,9 @@
 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;
@@ -38,7 +39,7 @@
 	 */
 	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()));
@@ -73,7 +74,7 @@
 	public int getDevicePartSupplyStatus() {
 		// Read the status property
 		Map<String, Object> property = (Map<String, Object>) aasServerConnection
-				.getModelPropertyValue(SubmodelElementProvider.PROPERTIES + "/partAvailability");
+				.getModelPropertyValue(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/SmartBaSyxTCPDeviceMockup.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/mockup/device/SmartBaSyxTCPDeviceMockup.java
index 0846b5c..ff94cfe 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
@@ -2,19 +2,22 @@
 
 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.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;
@@ -22,12 +25,13 @@
 /**
  * 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 +53,7 @@
 	 */
 	protected VABElementProxy aasServerConnection = null;
 
+	protected String aasPath;
 	
 	
 
@@ -68,7 +73,7 @@
 		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"));
+		setRegistry(new AASRegistryProxy("http://localhost:8080/" + BaSyxExamplesContext.REGISTRYURL));
 		setConnectionManager(new VABConnectionManager(new ExamplesPreconfiguredDirectory(), new HTTPConnectorProvider()));
 	}
 
@@ -83,10 +88,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");
+				.getModelPropertyValue(aasPath + "/submodels/Status/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/invocations");
 		int invocations = (int) property.get("value");
-		aasServerConnection.setModelPropertyValue("/aas/submodels/Status/" + SubmodelElementProvider.PROPERTIES + "/invocations/value", ++invocations);
+		aasServerConnection.setModelPropertyValue(aasPath + "/submodels/Status/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/invocations/value", ++invocations);
 	}
 
 	
@@ -99,7 +103,7 @@
 		super.onChangedExecutionState(newExecutionState);
 		
 		// Update property "properties/status" in external AAS
-		aasServerConnection.setModelPropertyValue("/aas/submodels/Status/" + SubmodelElementProvider.PROPERTIES + "/status/value",
+		aasServerConnection.setModelPropertyValue(aasPath + "/submodels/Status/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/status/value",
 				newExecutionState.getValue());
 	}
 
@@ -121,9 +125,14 @@
 		
 		// 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.setModelPropertyValue(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
@@ -141,7 +150,7 @@
 		invocationsProp.setIdShort("invocations");
 		statusSM.addSubModelElement(invocationsProp);
 		// - Transfer device sub model to server
-		aasServerConnection.createValue("/aas/submodels", statusSM);
+		aasServerConnection.setModelPropertyValue(aasPath + "/submodels/" + statusSM.getIdShort(), statusSM);
 
 		
 		// Register control component as local sub model
@@ -153,12 +162,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..3d36e49 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
@@ -2,18 +2,21 @@
 
 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.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;
@@ -29,7 +32,7 @@
  *
  */
 public class BaSyxTCPControlManufacturingDeviceManager extends TCPControllableDeviceManagerComponent implements ControlComponentChangeListener {
-	
+
 	/**
 	 * Initiates a logger using the current class
 	 */
@@ -40,6 +43,8 @@
 	 */
 	protected VABElementProxy aasServerConnection = null;
 
+	protected String aasPath;
+
 	
 	
 
@@ -52,7 +57,7 @@
 		
 		
 		// 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
@@ -63,7 +68,7 @@
 		
 		// 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);
 	}
 
 	
@@ -96,6 +101,7 @@
 		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
@@ -117,9 +123,10 @@
 		
 		// Push the AAS and submodels to the server
 		// - Transfer device AAS to server
-		aasServerConnection.createValue("/aas", aas);
+		aasServerConnection.setModelPropertyValue(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.setModelPropertyValue(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"));
@@ -177,15 +184,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.setModelPropertyValue(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.getModelPropertyValue(aasPath + "/submodels/Status/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/invocations");
 				int invocations = (int) property.get("value");
-				aasServerConnection.setModelPropertyValue("/aas/submodels/Status/" + SubmodelElementProvider.PROPERTIES + "/invocations/value", ++invocations);
+				aasServerConnection.setModelPropertyValue(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..52c9d82 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,5 +1,6 @@
 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;
@@ -57,7 +58,7 @@
 
 
 		// Transfer device sub model to server
-		aasServerConnection.createValue("/aas/submodels", supplySM);
+		aasServerConnection.setModelPropertyValue("/" + AASAggregatorProvider.PREFIX + "/" + lookupURN("AAS").getEncodedURN() + "/aas/submodels/" + supplySM.getIdShort(), supplySM);
 	}
 
 
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..99d6604 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
@@ -2,18 +2,21 @@
 
 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.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.protocol.http.connector.HTTPConnectorProvider;
 
 /**
@@ -57,28 +60,13 @@
 		
 		// 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
@@ -89,7 +77,7 @@
 		
 		// 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);
 	}
 
 
@@ -137,8 +125,9 @@
 		AssetAdministrationShell aas = new AssetAdministrationShell();
 		// - Populate AAS
 		aas.setIdShort("DeviceIDShort");
+		aas.setIdentification(lookupURN("AAS"));
 		// - Transfer device AAS to server
-		aasServerConnection.createValue("/aas", aas);
+		aasServerConnection.setModelPropertyValue(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
@@ -157,7 +146,7 @@
 		invocationsProp.setIdShort("invocations");
 		statusSM.addSubModelElement(invocationsProp);
 		// - Transfer device sub model to server
-		aasServerConnection.createValue("/aas/submodels/", statusSM);
+		aasServerConnection.setModelPropertyValue(AASAggregatorProvider.PREFIX + "/" + VABPathTools.encodePathElement(lookupURN("AAS").getId()) + "/aas/submodels/" + statusSM.getIdShort(), statusSM);
 	}
 
 
@@ -174,6 +163,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 +173,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.setModelPropertyValue(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.getModelPropertyValue(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.setModelPropertyValue(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/scenarios/cloudedgedeployment/TestCloudEdgeDeploymentScenario.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/scenarios/cloudedgedeployment/TestCloudEdgeDeploymentScenario.java
index 3459103..1a49332 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,8 @@
 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;
@@ -14,7 +14,9 @@
 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.proxy.AASRegistryProxy;
 import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
+import org.junit.AfterClass;
 import org.junit.BeforeClass;
 import org.junit.Test;
 
@@ -27,15 +29,22 @@
 		scenario = new CloudEdgeDeploymentScenario();
 	}
 	
+	@AfterClass
+	public static void tearDown() {
+		scenario.stop();
+	}
+
+	private IAASRegistryService 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);
@@ -68,7 +77,7 @@
 	@Test
 	public void testAAS() throws Exception {
 		ConnectedAssetAdministrationShellManager manager =
-				new ConnectedAssetAdministrationShellManager(scenario.registry);
+				new ConnectedAssetAdministrationShellManager(getRegistry());
 		
 		IAssetAdministrationShell aas = manager.retrieveAAS(scenario.aasIdentifier);
 		
@@ -90,7 +99,7 @@
 	@Test
 	public void testDocuSM() {
 		ConnectedAssetAdministrationShellManager manager =
-				new ConnectedAssetAdministrationShellManager(scenario.registry);
+				new ConnectedAssetAdministrationShellManager(getRegistry());
 		
 		ISubModel docuSM = manager.retrieveSubModel(scenario.aasIdentifier, scenario.docuSmIdentifier);
 		
@@ -107,7 +116,7 @@
 	@Test
 	public void testEdgeSM() {
 		ConnectedAssetAdministrationShellManager manager =
-				new ConnectedAssetAdministrationShellManager(scenario.registry);
+				new ConnectedAssetAdministrationShellManager(getRegistry());
 		
 		ISubModel edgeSM = manager.retrieveSubModel(scenario.aasIdentifier, scenario.edgeSmIdentifier);
 		
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..e2f6d3e 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
@@ -2,7 +2,7 @@
 
 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;
@@ -44,7 +44,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..89fb782 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
@@ -2,7 +2,7 @@
 
 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;
@@ -40,7 +40,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..e76244c 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
@@ -2,16 +2,18 @@
 
 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.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.junit.ClassRule;
@@ -54,7 +56,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 +96,7 @@
 
 		
 		// Change device operation mode
-		toControlComponent.setModelPropertyValue("status/opMode", "RegularMilling");
+		toControlComponent.setModelPropertyValue(VABPathTools.concatenatePaths(ControlComponent.STATUS, ControlComponent.OP_MODE), "RegularMilling");
 		// - Validate device operation mode
 		waitfor(() -> ((ControllableTCPDeviceMockup) context.getRunnable("Device")).getOpMode().equals("RegularMilling"));
 
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..4d8efd5 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
@@ -2,15 +2,17 @@
 
 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.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.junit.ClassRule;
@@ -53,7 +55,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 +89,7 @@
 		
 		
 		// Change device operation mode
-		toControlComponent.setModelPropertyValue("status/opMode", "RegularMilling");
+		toControlComponent.setModelPropertyValue(VABPathTools.concatenatePaths(ControlComponent.STATUS, ControlComponent.OP_MODE), "RegularMilling");
 		// - Validate device control component operation mode
 		waitfor( () -> ((SmartBaSyxTCPDeviceMockup) context.getRunnable("Device")).getControlComponent().getOperationMode().equals("RegularMilling") );
 
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..31050a1
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/scenarios/staticdynamic/TestStaticDynamicScenario.java
@@ -0,0 +1,58 @@
+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..1a5260c
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/AbstractSnippetTest.java
@@ -0,0 +1,76 @@
+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..4ab8821
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/TestAddSubmodelToAAS.java
@@ -0,0 +1,46 @@
+package org.eclipse.basyx.examples.snippets.aas;
+
+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/aas/TestDeleteAAS.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/TestDeleteAAS.java
new file mode 100644
index 0000000..f3d795f
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/TestDeleteAAS.java
@@ -0,0 +1,38 @@
+package org.eclipse.basyx.examples.snippets.aas;
+
+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 {
+			RetrieveRemoteAAS.retrieveRemoteAAS(aasIdentifier, registryComponent.getRegistryPath());
+			fail();
+		} catch (ResourceNotFoundException e) {
+		}
+		
+	}
+	
+}
\ No newline at end of file
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..504c406
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/TestDeleteSubmodelFromAAS.java
@@ -0,0 +1,40 @@
+package org.eclipse.basyx.examples.snippets.aas;
+
+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 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());
+		
+		// Try to retrieve deleted Submodel; should throw ResourceNotFoundException
+		try {
+			RetrieveSubmodelFromAAS.retrieveSubmodelFromAAS(
+					smIdentifier, aasIdentifier, registryComponent.getRegistryPath());
+			fail();
+		} catch (ResourceNotFoundException e) {
+		}
+		
+	}
+	
+}
\ No newline at end of file
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/TestLookupAAS.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/TestLookupAAS.java
new file mode 100644
index 0000000..339a0cc
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/TestLookupAAS.java
@@ -0,0 +1,34 @@
+package org.eclipse.basyx.examples.snippets.aas;
+
+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/aas/TestPushAASToServer.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/TestPushAASToServer.java
new file mode 100644
index 0000000..1b57fd1
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/TestPushAASToServer.java
@@ -0,0 +1,38 @@
+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.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/aas/TestRegisterAAS.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/TestRegisterAAS.java
new file mode 100644
index 0000000..717f533
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/TestRegisterAAS.java
@@ -0,0 +1,40 @@
+package org.eclipse.basyx.examples.snippets.aas;
+
+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/aas/TestRetrieveRemoteAAS.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/TestRetrieveRemoteAAS.java
new file mode 100644
index 0000000..933eed8
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/TestRetrieveRemoteAAS.java
@@ -0,0 +1,33 @@
+package org.eclipse.basyx.examples.snippets.aas;
+
+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 TestRetrieveRemoteAAS 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 =
+				RetrieveRemoteAAS.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/aas/TestRetrieveSubmodelFromAAS.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/TestRetrieveSubmodelFromAAS.java
new file mode 100644
index 0000000..03f98a8
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/aas/TestRetrieveSubmodelFromAAS.java
@@ -0,0 +1,36 @@
+package org.eclipse.basyx.examples.snippets.aas;
+
+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());
+	}
+	
+}
\ No newline at end of file
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/submodel/TestAddSubmodelElement.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/submodel/TestAddSubmodelElement.java
new file mode 100644
index 0000000..d7af892
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/submodel/TestAddSubmodelElement.java
@@ -0,0 +1,50 @@
+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/TestDeleteSubmodelElement.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/submodel/TestDeleteSubmodelElement.java
new file mode 100644
index 0000000..5da765a
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/submodel/TestDeleteSubmodelElement.java
@@ -0,0 +1,53 @@
+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) {
+		}
+		
+	}
+	
+}
\ No newline at end of file
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..6da88ae
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/submodel/TestExecuteOperation.java
@@ -0,0 +1,104 @@
+package org.eclipse.basyx.examples.snippets.submodel;
+
+import static org.junit.Assert.assertEquals;
+
+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.operation.Operation;
+import org.eclipse.basyx.vab.protocol.http.server.AASHTTPServer;
+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 AASHTTPServer 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];
+		});
+		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 AASHTTPServer(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/TestLookupSubmodel.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/submodel/TestLookupSubmodel.java
new file mode 100644
index 0000000..0305f12
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/submodel/TestLookupSubmodel.java
@@ -0,0 +1,36 @@
+package org.eclipse.basyx.examples.snippets.submodel;
+
+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/submodel/TestRegisterSubmodel.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/submodel/TestRegisterSubmodel.java
new file mode 100644
index 0000000..ea7c3bf
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/submodel/TestRegisterSubmodel.java
@@ -0,0 +1,45 @@
+package org.eclipse.basyx.examples.snippets.submodel;
+
+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.snippets.aas.RegisterAAS;
+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/TestRetrieveSubmodelElement.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/submodel/TestRetrieveSubmodelElement.java
new file mode 100644
index 0000000..7d8d03f
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/submodel/TestRetrieveSubmodelElement.java
@@ -0,0 +1,41 @@
+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());
+	}
+	
+}
\ No newline at end of file
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..7130114 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
@@ -6,7 +6,7 @@
 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;
@@ -43,7 +43,7 @@
 			    .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());
 
-	
+
 	/**
 	 * The BaSyx Deployment instantiates and starts context elements for this example. 
 	 * 
@@ -57,7 +57,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())
 			);
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..566f575 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
@@ -7,7 +7,7 @@
 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;
@@ -86,7 +86,7 @@
 			    .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());
 
-	
+
 	/**
 	 * The BaSyx Deployment instantiates and starts context elements for this example. 
 	 * 
@@ -100,7 +100,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())
 			);
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..05c4274 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
@@ -7,7 +7,7 @@
 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;
@@ -35,7 +35,7 @@
  */
 public class DynamicPropertyLambda {
 
-	
+
 	/**
 	 * VAB connection manager backend
 	 * 
@@ -62,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())
 			);
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..7002467 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
@@ -5,7 +5,7 @@
 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;
@@ -26,7 +26,7 @@
  */
 public class ManualHTTPCalls {
 
-	
+
 	/**
 	 * Create VAB connection manager backend
 	 * 
@@ -53,7 +53,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())
 			);
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/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/cfgprovider/CFGSubModelProvider.java b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/cfgprovider/CFGSubModelProvider.java
similarity index 94%
rename from components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/cfgprovider/CFGSubModelProvider.java
rename to sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/cfgprovider/CFGSubModelProvider.java
index fceb07d..e26dc5e 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/cfgprovider/CFGSubModelProvider.java
+++ b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/cfgprovider/CFGSubModelProvider.java
@@ -1,4 +1,4 @@
-package org.eclipse.basyx.components.cfgprovider;
+package org.eclipse.basyx.sandbox.components.cfgprovider;
 
 import java.util.Map;
 
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/cfgprovider/RawCFGSubModelProvider.java b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/cfgprovider/RawCFGSubModelProvider.java
similarity index 96%
rename from components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/cfgprovider/RawCFGSubModelProvider.java
rename to sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/cfgprovider/RawCFGSubModelProvider.java
index 405f33e..4d4a2c3 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/cfgprovider/RawCFGSubModelProvider.java
+++ b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/cfgprovider/RawCFGSubModelProvider.java
@@ -1,4 +1,4 @@
-package org.eclipse.basyx.components.cfgprovider;
+package org.eclipse.basyx.sandbox.components.cfgprovider;
 
 import java.util.HashMap;
 import java.util.Map;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/submodel/cfg/AbstractCFGSubModelProviderServlet.java b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/cfgprovider/servlet/AbstractCFGSubModelProviderServlet.java
similarity index 97%
rename from components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/submodel/cfg/AbstractCFGSubModelProviderServlet.java
rename to sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/cfgprovider/servlet/AbstractCFGSubModelProviderServlet.java
index c87d657..7198b6d 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/submodel/cfg/AbstractCFGSubModelProviderServlet.java
+++ b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/cfgprovider/servlet/AbstractCFGSubModelProviderServlet.java
@@ -1,4 +1,4 @@
-package org.eclipse.basyx.components.servlet.submodel.cfg;
+package org.eclipse.basyx.sandbox.components.cfgprovider.servlet;
 
 import java.io.IOException;
 import java.io.InputStream;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/submodel/cfg/CFGSubModelProviderServlet.java b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/cfgprovider/servlet/CFGSubModelProviderServlet.java
similarity index 83%
rename from components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/submodel/cfg/CFGSubModelProviderServlet.java
rename to sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/cfgprovider/servlet/CFGSubModelProviderServlet.java
index 1391f89..be1b334 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/submodel/cfg/CFGSubModelProviderServlet.java
+++ b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/cfgprovider/servlet/CFGSubModelProviderServlet.java
@@ -1,9 +1,9 @@
-package org.eclipse.basyx.components.servlet.submodel.cfg;
+package org.eclipse.basyx.sandbox.components.cfgprovider.servlet;
 
 import java.util.Properties;
 
-import org.eclipse.basyx.components.cfgprovider.CFGSubModelProvider;
 import org.eclipse.basyx.components.provider.BaseConfiguredProvider;
+import org.eclipse.basyx.sandbox.components.cfgprovider.CFGSubModelProvider;
 import org.eclipse.basyx.submodel.restapi.SubModelProvider;
 
 /**
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/submodel/cfg/RawCFGSubModelProviderServlet.java b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/cfgprovider/servlet/RawCFGSubModelProviderServlet.java
similarity index 82%
rename from components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/submodel/cfg/RawCFGSubModelProviderServlet.java
rename to sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/cfgprovider/servlet/RawCFGSubModelProviderServlet.java
index 9a87495..0087b4c 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/submodel/cfg/RawCFGSubModelProviderServlet.java
+++ b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/cfgprovider/servlet/RawCFGSubModelProviderServlet.java
@@ -1,8 +1,8 @@
-package org.eclipse.basyx.components.servlet.submodel.cfg;
+package org.eclipse.basyx.sandbox.components.cfgprovider.servlet;
 
 import java.util.Properties;
 
-import org.eclipse.basyx.components.cfgprovider.RawCFGSubModelProvider;
+import org.eclipse.basyx.sandbox.components.cfgprovider.RawCFGSubModelProvider;
 import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
 import org.eclipse.basyx.submodel.restapi.SubModelProvider;
 
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/directory/AASDirectoryEntry.java b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/registry/AASDirectoryEntry.java
similarity index 97%
rename from components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/directory/AASDirectoryEntry.java
rename to sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/registry/AASDirectoryEntry.java
index 84589ef..34fdbdb 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/directory/AASDirectoryEntry.java
+++ b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/registry/AASDirectoryEntry.java
@@ -1,9 +1,9 @@
-package org.eclipse.basyx.components.directory;
+package org.eclipse.basyx.sandbox.components.registry;
 
 import java.util.Collection;
 import java.util.HashSet;
 
-import org.eclipse.basyx.components.directory.exception.AASDirectoryFormatException;
+import org.eclipse.basyx.sandbox.components.registry.exception.AASDirectoryFormatException;
 
 
 
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/registry/StaticCFGDirectoryServlet.java b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/registry/StaticCFGDirectoryServlet.java
similarity index 97%
rename from components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/registry/StaticCFGDirectoryServlet.java
rename to sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/registry/StaticCFGDirectoryServlet.java
index 57d0cbf..db4f329 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/registry/StaticCFGDirectoryServlet.java
+++ b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/registry/StaticCFGDirectoryServlet.java
@@ -1,4 +1,4 @@
-package org.eclipse.basyx.components.servlet.registry;
+package org.eclipse.basyx.sandbox.components.registry;
 
 
 import java.io.IOException;
@@ -15,8 +15,7 @@
 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.sandbox.components.registry.exception.AASDirectoryProviderException;
 import org.eclipse.basyx.vab.protocol.http.server.BasysHTTPServlet;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/directory/exception/AASDirectoryFormatException.java b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/registry/exception/AASDirectoryFormatException.java
similarity index 87%
rename from components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/directory/exception/AASDirectoryFormatException.java
rename to sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/registry/exception/AASDirectoryFormatException.java
index 79aacf2..93e57a6 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/directory/exception/AASDirectoryFormatException.java
+++ b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/registry/exception/AASDirectoryFormatException.java
@@ -1,4 +1,4 @@
-package org.eclipse.basyx.components.directory.exception;
+package org.eclipse.basyx.sandbox.components.registry.exception;
 
 
 
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/directory/exception/AASDirectoryProviderException.java b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/registry/exception/AASDirectoryProviderException.java
similarity index 87%
rename from components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/directory/exception/AASDirectoryProviderException.java
rename to sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/registry/exception/AASDirectoryProviderException.java
index 30edf58..ade137b 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/directory/exception/AASDirectoryProviderException.java
+++ b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/registry/exception/AASDirectoryProviderException.java
@@ -1,4 +1,4 @@
-package org.eclipse.basyx.components.directory.exception;
+package org.eclipse.basyx.sandbox.components.registry.exception;
 
 
 
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/SQLPreconfiguredSubModelProvider.java b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/sqlprovider/SQLPreconfiguredSubModelProvider.java
similarity index 97%
rename from components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/SQLPreconfiguredSubModelProvider.java
rename to sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/sqlprovider/SQLPreconfiguredSubModelProvider.java
index 43dc58e..4360636 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/SQLPreconfiguredSubModelProvider.java
+++ b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/sqlprovider/SQLPreconfiguredSubModelProvider.java
@@ -1,4 +1,4 @@
-package org.eclipse.basyx.components.sqlprovider;
+package org.eclipse.basyx.sandbox.components.sqlprovider;
 
 import java.util.Collection;
 import java.util.HashMap;
@@ -8,10 +8,10 @@
 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.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;
@@ -296,6 +296,7 @@
 	/**
 	 * Split a whitespace delimited string
 	 */
+	@Override
 	protected Collection<String> splitString(String input) {
 		// Return value
 		HashSet<String> result = new HashSet<>();
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/SQLProviderTestOLD.java b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/sqlprovider/SQLProviderTestOLD.java
similarity index 95%
rename from components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/SQLProviderTestOLD.java
rename to sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/sqlprovider/SQLProviderTestOLD.java
index 772b1ee..c2a5344 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/SQLProviderTestOLD.java
+++ b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/sqlprovider/SQLProviderTestOLD.java
@@ -1,12 +1,12 @@
-package org.eclipse.basyx.components.sqlprovider;
+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.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;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/SQLSubModelProvider.java b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/sqlprovider/SQLSubModelProvider.java
similarity index 97%
rename from components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/SQLSubModelProvider.java
rename to sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/sqlprovider/SQLSubModelProvider.java
index 59697d6..38914d3 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/sqlprovider/SQLSubModelProvider.java
+++ b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/sqlprovider/SQLSubModelProvider.java
@@ -1,4 +1,4 @@
-package org.eclipse.basyx.components.sqlprovider;
+package org.eclipse.basyx.sandbox.components.sqlprovider;
 
 import java.util.Collection;
 import java.util.HashMap;
@@ -8,10 +8,10 @@
 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.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;
@@ -23,7 +23,7 @@
  * Asset administration shell sub model provider that connects to SQL database
  * 
  * @author kuhn
- *
+ * 
  */
 public class SQLSubModelProvider extends BaseConfiguredProvider {
 
@@ -294,6 +294,7 @@
 	/**
 	 * Split a whitespace delimited string
 	 */
+	@Override
 	protected Collection<String> splitString(String input) {
 		// Return value
 		HashSet<String> result = new HashSet<>();
diff --git a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/submodel/SQLSubModelProviderServlet.java b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/sqlprovider/servlet/SQLSubModelProviderServlet.java
similarity index 92%
rename from components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/submodel/SQLSubModelProviderServlet.java
rename to sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/sqlprovider/servlet/SQLSubModelProviderServlet.java
index 7de51c7..7ee2fab 100644
--- a/components/basys.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/servlet/submodel/SQLSubModelProviderServlet.java
+++ b/sandbox/Java/basyx.sandbox/src/main/java/org/eclipse/basyx/sandbox/components/sqlprovider/servlet/SQLSubModelProviderServlet.java
@@ -1,4 +1,4 @@
-package org.eclipse.basyx.components.servlet.submodel;
+package org.eclipse.basyx.sandbox.components.sqlprovider.servlet;
 
 import java.io.IOException;
 import java.io.InputStream;
@@ -8,7 +8,7 @@
 
 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.sandbox.components.sqlprovider.SQLPreconfiguredSubModelProvider;
 import org.eclipse.basyx.vab.protocol.http.server.VABHTTPInterface;
 
 /**
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/examples/basys.examples/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
similarity index 93%
rename from examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/code/BaSyxCreateProvideUseExampleAASSubmodel.java
rename to sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/code/BaSyxCreateProvideUseExampleAASSubmodel.java
index dc700af..9ca9e9d 100644
--- a/examples/basys.examples/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
@@ -7,7 +7,7 @@
 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.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;
@@ -56,7 +56,7 @@
 		JSONConnector toDeviceManager = new JSONConnector(basyxConnector);	
 		// - Access sub model property, check value
 		Map<String, Object> property = (Map<String, Object>) toDeviceManager
-				.getModelPropertyValue(SubmodelElementProvider.PROPERTIES + "/status");
+				.getModelPropertyValue(MultiSubmodelElementProvider.ELEMENTS + "/status");
 		assertEquals("offline", property.get("value"));
 		
 		
diff --git a/examples/basys.examples/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
similarity index 82%
rename from examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/connection/servlet/AASServletConnection.java
rename to sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/connection/servlet/AASServletConnection.java
index 59b886f..10a4bb7 100644
--- a/examples/basys.examples/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
@@ -16,7 +16,7 @@
 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.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;
@@ -55,7 +55,7 @@
 			// - Add container property that holds other properties
 			SubmodelElementCollection container = new SubmodelElementCollection();
 			container.setIdShort("prop2");
-			container.addElement(prop11);
+			container.addSubModelElement(prop11);
 			// - Add container to property map
 			addSubModelElement(container);
 
@@ -75,7 +75,7 @@
 			// 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/"),
+					.addSubmodelMapping("aas-001", "sm-001", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/SampleModel/submodel"),
 			// We connect via HTTP
 			new HTTPConnectorProvider());
 	
@@ -88,7 +88,7 @@
 			// 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/"),
+					.addMapping("sm-001VAB", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/SampleModel/submodel"),
 			// We connect via HTTP
 			new HTTPConnectorProvider());
 
@@ -116,26 +116,26 @@
 		// - 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((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").get() == 123);
+		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(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(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(SubmodelElementProvider.PROPERTIES + "/prop1/value", 456);
+		connSubModel1.setModelPropertyValue(MultiSubmodelElementProvider.ELEMENTS + "/prop1/value", 456);
 		// - Read value back using VAB primitive
-		assertTrue((int) ((Map<String, Object>) connSubModel1.getModelPropertyValue(SubmodelElementProvider.PROPERTIES + "/prop1")).get("value") == 456);
+		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").get() == 456);
+		assertTrue((int) subModel.getProperties().get("prop1").getValue() == 456);
 	}
 }
 
diff --git a/examples/basys.examples/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
similarity index 82%
rename from examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/connection/servlet/AASServletConnectionFull.java
rename to sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/connection/servlet/AASServletConnectionFull.java
index 9e919e8..707398b 100644
--- a/examples/basys.examples/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
@@ -16,7 +16,7 @@
 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.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;
@@ -58,7 +58,7 @@
 			// - Add container property that holds other properties
 			SubmodelElementCollection container = new SubmodelElementCollection();
 			container.setIdShort("prop2");
-			container.addElement(prop11);
+			container.addSubModelElement(prop11);
 			// - Add container to property map
 			addSubModelElement(container);
 
@@ -79,10 +79,10 @@
 			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/")
+					.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/"),
+					.addMapping("sm-001MVAB", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/SampleModelManual/submodel"),
 			// We connect via HTTP
 			new HTTPConnectorProvider());
 	
@@ -95,7 +95,7 @@
 			// 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/"),
+					.addSubmodelMapping("aas-001", "sm-001", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/SampleModel/submodel"),
 			// We connect via HTTP
 			new HTTPConnectorProvider());
 
@@ -123,27 +123,27 @@
 		// - 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((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").get() == 123);
+		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(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(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(SubmodelElementProvider.PROPERTIES + "/prop1/value", 456);
+		connSubModel1.setModelPropertyValue(MultiSubmodelElementProvider.ELEMENTS + "/prop1/value", 456);
 		// - Read value back using VAB primitive
-		assertTrue((int) ((Map<String, Object>) connSubModel1.getModelPropertyValue(SubmodelElementProvider.PROPERTIES + "/prop1")).get("value") == 456);
+		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").get() == 456);
+		assertTrue((int) subModel.getProperties().get("prop1").getValue() == 456);
 	}
 }
 
diff --git a/examples/basys.examples/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
similarity index 90%
rename from examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/connection/servlet/AASSubModelServletConnectorConnection.java
rename to sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/connection/servlet/AASSubModelServletConnectorConnection.java
index d3f4e0e..59152d1 100644
--- a/examples/basys.examples/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
@@ -57,7 +57,7 @@
 			// - Add container property that holds other properties
 			SubmodelElementCollection container = new SubmodelElementCollection();
 			container.setIdShort("prop2");
-			container.addElement(prop11);
+			container.addSubModelElement(prop11);
 			// - Add container to property map
 			addSubModelElement(container);
 
@@ -78,7 +78,7 @@
 			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"),
+					.addSubmodelMapping("aas-001", "sm-001", "http://localhost:8080/basys.examples/Testsuite/components/BaSys/1.0/SampleModel/submodel"),
 			// We connect via HTTP
 			new HTTPConnectorProvider());
 
@@ -89,7 +89,7 @@
 			// 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"),
+					.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());
 
@@ -120,13 +120,13 @@
 		// - 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((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").get());
+		assertEquals(123, properties.get("prop11").getValue());
 	}
 }
 
diff --git a/examples/basys.examples/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
similarity index 75%
rename from examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/connection/servlet/AASSubModelServletVABConnection.java
rename to sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/connection/servlet/AASSubModelServletVABConnection.java
index 6138225..6e4e498 100644
--- a/examples/basys.examples/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
@@ -11,7 +11,7 @@
 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.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;
@@ -28,8 +28,8 @@
  */
 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 {
@@ -52,7 +52,7 @@
 			// - Add container property that holds other properties
 			SubmodelElementCollection container = new SubmodelElementCollection();
 			container.setIdShort("prop2");
-			container.addElement(prop11);
+			container.addSubModelElement(prop11);
 			// - Add container to property map
 			addSubModelElement(container);
 
@@ -74,9 +74,9 @@
 			// 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"),
+					.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());
 
@@ -103,15 +103,15 @@
 		// 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);
+		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(SubmodelElementProvider.PROPERTIES + "/prop1/value", 456);
+		connSubModel1.setModelPropertyValue(MultiSubmodelElementProvider.ELEMENTS + "/prop1/value", 456);
 		// - Read value back using VAB primitive
-		assertTrue((int) ((Map<String, Object>) connSubModel1.getModelPropertyValue(SubmodelElementProvider.PROPERTIES + "/prop1/value")).get("value") == 456);
+		assertTrue((Integer) connSubModel1.getModelPropertyValue(MultiSubmodelElementProvider.ELEMENTS + "/prop1/value") == 456);
 	}
 }
 
diff --git a/examples/basys.examples/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
similarity index 97%
rename from examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/dynamic/RunAASDynamicOperationSnippet.java
rename to sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/dynamic/RunAASDynamicOperationSnippet.java
index cd59adf..bd0243c 100644
--- a/examples/basys.examples/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
@@ -7,7 +7,7 @@
 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.submodel.metamodel.map.SubModel;
@@ -48,7 +48,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())
 			);
diff --git a/examples/basys.examples/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
similarity index 97%
rename from examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/dynamic/RunAASManualHTTPOperationsSnippet.java
rename to sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/dynamic/RunAASManualHTTPOperationsSnippet.java
index 8da4b52..3be7c43 100644
--- a/examples/basys.examples/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
@@ -5,7 +5,7 @@
 import java.util.Map;
 
 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.submodel.metamodel.map.SubModel;
@@ -46,7 +46,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())
 			);
diff --git a/examples/basys.examples/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
similarity index 97%
rename from examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/dynamic/RunAASPropertiesCRUDAccessSnippet.java
rename to sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/dynamic/RunAASPropertiesCRUDAccessSnippet.java
index 74adbfa..8f7d879 100644
--- a/examples/basys.examples/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
@@ -4,7 +4,7 @@
 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.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;
@@ -45,7 +45,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())
 			);
diff --git a/examples/basys.examples/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
similarity index 97%
rename from examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/dynamic/RunAASTailoredSupplierSnippet.java
rename to sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/aas/dynamic/RunAASTailoredSupplierSnippet.java
index 379a696..d08cd3b 100644
--- a/examples/basys.examples/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
@@ -7,7 +7,7 @@
 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.submodel.metamodel.map.SubModel;
@@ -85,7 +85,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())
 			);
diff --git a/examples/basys.examples/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
similarity index 96%
rename from examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/vab/connection/RunAASManualHTTPOperationsSnippet.java
rename to sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/vab/connection/RunAASManualHTTPOperationsSnippet.java
index 3fb38c5..b643870 100644
--- a/examples/basys.examples/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
@@ -5,7 +5,7 @@
 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;
@@ -43,7 +43,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())
 			);
diff --git a/examples/basys.examples/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
similarity index 96%
rename from examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/undoc/vab/connection/RunAASPropertiesSnippet.java
rename to sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/examples/snippets/undoc/vab/connection/RunAASPropertiesSnippet.java
index ed3a544..730cfd5 100644
--- a/examples/basys.examples/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
@@ -6,7 +6,7 @@
 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;
@@ -45,7 +45,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())
 			);
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/cfgprovider/TestCFGProvider.java b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/cfgprovider/TestCFGProvider.java
similarity index 96%
rename from components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/cfgprovider/TestCFGProvider.java
rename to sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/cfgprovider/TestCFGProvider.java
index 655af40..ffa29dc 100644
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/cfgprovider/TestCFGProvider.java
+++ b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/cfgprovider/TestCFGProvider.java
@@ -1,4 +1,4 @@
-package org.eclipse.basyx.regression.cfgprovider;
+package org.eclipse.basyx.sandbox.regression.components.cfgprovider;
 
 import static org.junit.Assert.assertEquals;
 
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/cfgprovider/TestCFGProviderPropertyMetaData.java b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/cfgprovider/TestCFGProviderPropertyMetaData.java
similarity index 97%
rename from components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/cfgprovider/TestCFGProviderPropertyMetaData.java
rename to sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/cfgprovider/TestCFGProviderPropertyMetaData.java
index 4af91ac..22f824e 100644
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/cfgprovider/TestCFGProviderPropertyMetaData.java
+++ b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/cfgprovider/TestCFGProviderPropertyMetaData.java
@@ -1,4 +1,4 @@
-package org.eclipse.basyx.regression.cfgprovider;
+package org.eclipse.basyx.sandbox.regression.components.cfgprovider;
 
 import static org.junit.Assert.assertEquals;
 
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/cfgprovider/TestCFGProviderSubmodelMetaData.java b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/cfgprovider/TestCFGProviderSubmodelMetaData.java
similarity index 96%
rename from components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/cfgprovider/TestCFGProviderSubmodelMetaData.java
rename to sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/cfgprovider/TestCFGProviderSubmodelMetaData.java
index d38a7de..a3dfb92 100644
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/cfgprovider/TestCFGProviderSubmodelMetaData.java
+++ b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/cfgprovider/TestCFGProviderSubmodelMetaData.java
@@ -1,4 +1,4 @@
-package org.eclipse.basyx.regression.cfgprovider;
+package org.eclipse.basyx.sandbox.regression.components.cfgprovider;
 
 import static org.junit.Assert.assertEquals;
 
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/directory/file/TestAASDirectoryEntry.java b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/directory/file/TestAASDirectoryEntry.java
similarity index 97%
rename from components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/directory/file/TestAASDirectoryEntry.java
rename to sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/directory/file/TestAASDirectoryEntry.java
index 662b48f..7ad49ce 100644
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/directory/file/TestAASDirectoryEntry.java
+++ b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/directory/file/TestAASDirectoryEntry.java
@@ -1,9 +1,9 @@
-package org.eclipse.basyx.regression.directory.file;
+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.components.directory.AASDirectoryEntry;
+import org.eclipse.basyx.sandbox.components.registry.AASDirectoryEntry;
 import org.junit.Test;
 
 
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/directory/file/TestStaticDirectoryFileProvider.java b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/directory/file/TestStaticDirectoryFileProvider.java
similarity index 97%
rename from components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/directory/file/TestStaticDirectoryFileProvider.java
rename to sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/directory/file/TestStaticDirectoryFileProvider.java
index 9449904..0395d56 100644
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/directory/file/TestStaticDirectoryFileProvider.java
+++ b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/directory/file/TestStaticDirectoryFileProvider.java
@@ -1,4 +1,4 @@
-package org.eclipse.basyx.regression.directory.file;
+package org.eclipse.basyx.sandbox.regression.components.directory.file;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/directory/file/TestStaticDirectoryFileProviderExceptions.java b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/directory/file/TestStaticDirectoryFileProviderExceptions.java
similarity index 96%
rename from components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/directory/file/TestStaticDirectoryFileProviderExceptions.java
rename to sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/directory/file/TestStaticDirectoryFileProviderExceptions.java
index 54e4749..369c60d 100644
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/directory/file/TestStaticDirectoryFileProviderExceptions.java
+++ b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/directory/file/TestStaticDirectoryFileProviderExceptions.java
@@ -1,4 +1,4 @@
-package org.eclipse.basyx.regression.directory.file;
+package org.eclipse.basyx.sandbox.regression.components.directory.file;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.fail;
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/rawcfgprovider/TestRawCFGProviderAAS.java b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/rawcfgprovider/TestRawCFGProviderAAS.java
similarity index 96%
rename from components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/rawcfgprovider/TestRawCFGProviderAAS.java
rename to sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/rawcfgprovider/TestRawCFGProviderAAS.java
index 1ef899b..c113a3f 100644
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/rawcfgprovider/TestRawCFGProviderAAS.java
+++ b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/rawcfgprovider/TestRawCFGProviderAAS.java
@@ -1,4 +1,4 @@
-package org.eclipse.basyx.regression.rawcfgprovider;
+package org.eclipse.basyx.sandbox.regression.components.rawcfgprovider;
 
 import static org.junit.Assert.assertEquals;
 
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/rawcfgprovider/TestRawCFGProviderAASNewModel.java b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/rawcfgprovider/TestRawCFGProviderAASNewModel.java
similarity index 96%
rename from components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/rawcfgprovider/TestRawCFGProviderAASNewModel.java
rename to sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/rawcfgprovider/TestRawCFGProviderAASNewModel.java
index 8f9efc0..784ed50 100644
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/rawcfgprovider/TestRawCFGProviderAASNewModel.java
+++ b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/rawcfgprovider/TestRawCFGProviderAASNewModel.java
@@ -1,4 +1,4 @@
-package org.eclipse.basyx.regression.rawcfgprovider;
+package org.eclipse.basyx.sandbox.regression.components.rawcfgprovider;
 
 import static org.junit.Assert.assertEquals;
 
diff --git a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/rawcfgprovider/TestRawCFGProviderSimpleValues.java b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/rawcfgprovider/TestRawCFGProviderSimpleValues.java
similarity index 94%
rename from components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/rawcfgprovider/TestRawCFGProviderSimpleValues.java
rename to sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/rawcfgprovider/TestRawCFGProviderSimpleValues.java
index ef95857..4863157 100644
--- a/components/basys.components/basyx.components.lib/src/test/java/org/eclipse/basyx/regression/rawcfgprovider/TestRawCFGProviderSimpleValues.java
+++ b/sandbox/Java/basyx.sandbox/src/test/java/org/eclipse/basyx/sandbox/regression/components/rawcfgprovider/TestRawCFGProviderSimpleValues.java
@@ -1,4 +1,4 @@
-package org.eclipse.basyx.regression.rawcfgprovider;
+package org.eclipse.basyx.sandbox.regression.components.rawcfgprovider;
 
 import static org.junit.Assert.assertEquals;
 
@@ -56,7 +56,7 @@
 
 		// Get property value
 		Map<String, Object> value1 = (Map<String, Object>) connSubModel
-				.getModelPropertyValue("/aas/submodels/rawSampleCFG/submodelElements/cfgProperty1/value");
+				.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");
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..68639c3
--- /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 "xsd::boolean";
+      case type::valueType::Int:
+        return "xsd::integer";
+      case type::valueType::Float:
+        return "xsd::float";
+      case type::valueType::String:
+        return "xsd::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 "xsd: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 "xsd: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 "xsd: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 "xsd: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 "xsd: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 "xsd: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 "xsd: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 "xsd: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 "xsd: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 "xsd: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 "xsd: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 "xsd: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 "xsd: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 "xsd: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 "xsd: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 "xsd: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 "xsd: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 "xsd: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 "xsd: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 "xsd: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 "xsd: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/map_v2/SubModel.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/SubModel.h
index 7611de1..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;
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 7fa8855..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;
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 c972137..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
@@ -23,7 +23,10 @@
 	public virtual vab::ElementMap
 {
 public:
-	using asset_t = basyx::submodel::map::Asset;
+  struct Path {
+    static constexpr char Submodels[] = "submodels";
+    static constexpr char Asset[] = "asset";
+  };
 private:
 	Reference derivedFrom;
 	Asset asset;
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 84eaea1..4d7b630 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
@@ -16,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
 {
@@ -99,7 +103,7 @@
 	auto & obj = objectList.at(n);
 
 	// Get id of object and create temporary
-	const auto & id = obj.getProperty(map::Identifiable::Path::IdShort).template Get<std::string&>();
+	const auto & id = obj.getProperty(ElementContainerPath::IdShort).Get<std::string&>();
 	return this->getElement(id);
 };
 
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 2dc836b..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,19 +32,15 @@
 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")
-            .template Get<std::string&>();
-	
-        return ModelTypes_::from_string(model_type);
+	auto model_type = this->map.getProperty(ModelTypePath::ModelType).getProperty(ModelTypePath::Name).Get<std::string&>();
+	return ModelTypes_::from_string(model_type);
 };
 
 }
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 276eddd..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
@@ -17,6 +17,11 @@
 	public virtual vab::ElementMap
 {
 public:
+  struct Path {
+    static constexpr char Dependencies[] = "dependencies";
+  };
+
+public:
 	using vab::ElementMap::ElementMap;
 
 	Formula();
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 efa29ec..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
@@ -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:
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 634de08..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
@@ -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);
 
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 09cae0a..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
@@ -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);
 
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 4d03ade..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
@@ -19,6 +19,12 @@
   , 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;
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
index b85b2d6..c3aa385 100644
--- 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
@@ -16,6 +16,12 @@
   , 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);
 
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 47b55fa..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
@@ -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:
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 694ec37..b50fb5a 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
@@ -13,6 +13,13 @@
 	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[] = "identifier";
+  };
 private:
 	map::AdministrativeInformation administrativeInformation;
 public:
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 37b1f7d..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
@@ -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);
 
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 ff60434..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
@@ -14,11 +14,17 @@
 namespace map {
 
 class SubmodelElement
-    : public virtual api::ISubmodelElement,
-      public virtual vab::ElementMap,
-      public virtual Qualifiable,
-      public Referable,
-      public HasDataSpecification {
+  :	public virtual api::ISubmodelElement
+  , public virtual vab::ElementMap
+  , public virtual Qualifiable
+  , public Referable
+  , public HasDataSpecification
+{
+public:
+  struct Path {
+    static constexpr char Kind[] = "kind";
+    static constexpr char SemanticId[] = "semanticId";
+  };
 private:
     Reference semanticId;
 
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 a149778..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;
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..670ad91 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;
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 62fbad3..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;
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 042adfe..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
@@ -5,6 +5,7 @@
 #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>
 
@@ -12,78 +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 virtual Qualifiable
-  , 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");
-	}
-
-	virtual const Reference * const getValueId() const override
-	{
-		if (&this->valueId)
+    // or if it's a primitive type, not null or object
+    if (object.GetObjectType() == type::objectType::Primitive)
     {
-		  return this->valueId.get();
+      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()));
     }
-		return nullptr;
-	}
+  }
 
-	virtual void setValueId(const api::IReference & valueId) override
-	{
-	  this->valueId = util::make_unique<Reference>(valueId);
-	  this->map.insertKey("valueId", this->valueId->getMap());
-	}
+  virtual basyx::object getObject() override
+  {
+    return this->map.getProperty(PropertyPath::Value);
+  }
 
-	virtual KeyElements getKeyElementType() const override { return KeyElements::Property; };
+  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 77d6001..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
@@ -14,6 +14,11 @@
                          public SubmodelElement,
                          public ModelType<ModelTypes::ReferenceElement> 
 {
+public:
+  struct Path {
+    static constexpr char Value[] = "value";
+    static constexpr char Kind[] = "kind";
+  };
 private:
     Reference value;
 public:
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/submodelelement/property/Property.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/submodelelement/property/Property.h
index 53eb81a..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
@@ -69,6 +69,8 @@
 	{
 		this->valueId = valueId;
 	}
+
+  virtual KeyElements getKeyElementType() const override { return KeyElements::Property; };
 };
 
 }
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/CMakeLists.txt b/sdks/c++/basys.sdk.cc/src/submodel/CMakeLists.txt
index da4b7eb..10ad2b5 100644
--- a/sdks/c++/basys.sdk.cc/src/submodel/CMakeLists.txt
+++ b/sdks/c++/basys.sdk.cc/src/submodel/CMakeLists.txt
@@ -23,6 +23,8 @@
 
 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
@@ -67,6 +69,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
@@ -151,6 +165,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
@@ -197,6 +212,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
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 dd88992..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,14 +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.getKeyMap());
-	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 a9f1c49..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;
 
+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
index 226e10b..5a35320 100644
--- 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
@@ -7,38 +7,41 @@
 
 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("version", version);
-  this->map.insertKey("revision", revision);
+  this->map.insertKey(Path::Version, version);
+  this->map.insertKey(Path::Revision, revision);
 }
 
 void AdministrativeInformation::setVersion(const std::string &version)
 {
-  this->map.insertKey("version", version);
+  this->map.insertKey(Path::Version, version);
 }
 
 void AdministrativeInformation::setRevision(const std::string &revision)
 {
-  this->map.insertKey("revision", revision);
+  this->map.insertKey(Path::Revision, revision);
 }
 
 bool AdministrativeInformation::hasVersion() const
 {
-  return not this->map.getProperty("version").IsNull();
+  return not this->map.getProperty(Path::Version).IsNull();
 }
 
 bool AdministrativeInformation::hasRevision() const
 {
-  return not this->map.getProperty("revision").IsNull();
+  return not this->map.getProperty(Path::Revision).IsNull();
 }
 
 const std::string * const AdministrativeInformation::getVersion() const
 {
-  auto version = this->map.getProperty("version");
+  auto version = this->map.getProperty(Path::Version);
   if (version.IsNull())
     return nullptr;
 
@@ -47,7 +50,7 @@
 
 const std::string * const AdministrativeInformation::getRevision() const
 {
-  auto revision = this->map.getProperty("revision");
+  auto revision = this->map.getProperty(Path::Revision);
   if (revision.IsNull())
     return nullptr;
 
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..fafd9df 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, basyx::object::make_object_ref(&dataSpecification));
 }
 
 void HasDataSpecification::addDataSpecification(const simple::Reference & reference)
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 32ce682..c6abe71 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,37 +4,32 @@
 using namespace basyx::submodel::map;
 using namespace basyx::submodel::api;
 
-struct IdentifierPath {
-	static constexpr char IdType[] = "idType";
-	static constexpr char Id[] = "id";
-  static constexpr char AdministrativeInformation[] = "AdministrativeInformation";
-};
-
-constexpr char IdentifierPath::IdType[];
-constexpr char IdentifierPath::Id[];
-constexpr char IdentifierPath::AdministrativeInformation[];
+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 not this->map.getProperty(IdentifierPath::AdministrativeInformation).IsNull();
+  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&>()
 	};
 }
 
@@ -51,5 +46,5 @@
 void Identifiable::setAdministrativeInformation(const AdministrativeInformation &administrativeInformation)
 {
   this->administrativeInformation = administrativeInformation;
-  this->map.insertKey(IdentifierPath::AdministrativeInformation, this->administrativeInformation.getMap());
+  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 131eaf3..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("qualifiers", 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("qualifiers").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("qualifiers").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("qualifiers").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("qualifiers").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/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 049df97..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,15 +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("invokable", this->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/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/tests/regression/submodel/CMakeLists.txt b/sdks/c++/basys.sdk.cc/tests/regression/submodel/CMakeLists.txt
index 5ba14b3..7caa12e 100644
--- a/sdks/c++/basys.sdk.cc/tests/regression/submodel/CMakeLists.txt
+++ b/sdks/c++/basys.sdk.cc/tests/regression/submodel/CMakeLists.txt
@@ -27,6 +27,7 @@
 	api/parts/test_View.cpp
 	api/property/test_Property.cpp
 	api/common/test_LangStringSet.cpp
+	api/property/test_Property.cpp
 	map_v2/test_Submodel.cpp
 	map_v2/common/test_ElementContainer.cpp
 	map_v2/dataspecification/test_DataSpecification.cpp
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
index 93911bc..23144ad 100644
--- 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
@@ -10,20 +10,23 @@
 
 using namespace basyx::submodel;
 
-using ImplTypes = ::testing::Types<map::AssetAdministrationShell, simple::AssetAdministrationShell>;
+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 = Impl;
+  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>("testAas", 
+		aas = util::make_unique<impl_t>("testAas",
 			simple::Identifier::Custom("testAas"), 
-			typename Impl::asset_t{ "testAsset", simple::Identifier::Custom("testAsset") }
+			asset_t{ "testAsset", simple::Identifier::Custom("testAsset") }
 			);
 	}
 
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
index 6cac43c..f0de4ca 100644
--- 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
@@ -1,6 +1,7 @@
 #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;
 
@@ -56,5 +57,259 @@
   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("xsd:anyURI"));
+}
+
+TYPED_TEST(PropertyTest, TestSafeDateTime)
+{
+  map::Property<simple::DateTime> dateTime_property("test id");
+  std::string valueType = dateTime_property.getValueType();
+  ASSERT_EQ(valueType, std::string("xsd: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("xsd: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("xsd: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("xsd: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("xsd: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("xsd: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("xsd: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("xsd: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("xsd: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("xsd: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/java/basys.sdk/pom.xml b/sdks/java/basys.sdk/pom.xml
index 534a2a9..9fd83b1 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>0.1.0-SNAPSHOT</version>
 	<name>BaSyx SDK</name>
 
 	<packaging>jar</packaging>
@@ -175,4 +175,5 @@
     		<version>2.7.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..966a1d2 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
@@ -8,10 +8,13 @@
 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.IAASRegistryService;
 import org.eclipse.basyx.aas.restapi.AASModelProvider;
 import org.eclipse.basyx.aas.restapi.VABMultiSubmodelProvider;
 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.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
 
 /**
  * An implementation of the IAASAggregator interface using maps internally
@@ -23,6 +26,24 @@
 
 	protected Map<String, VABMultiSubmodelProvider> aasProviderMap = new HashMap<>();
 
+	protected IAASRegistryService registry;
+
+	/**
+	 * Constructs default AAS Aggregator
+	 */
+	public AASAggregator() {
+	}
+
+	/**
+	 * Constructs AAS Aggregator using the passed registry. This registry is used to
+	 * resolve requests for remote submodels
+	 * 
+	 * @param registry
+	 */
+	public AASAggregator(IAASRegistryService registry) {
+		this.registry = registry;
+	}
+
 	@SuppressWarnings("unchecked")
 	@Override
 	public Collection<IAssetAdministrationShell> getAASList() {
@@ -43,14 +64,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.getModelPropertyValue("/aas");
 		IAssetAdministrationShell aas = AssetAdministrationShell.createAsFacade(aasMap);
 
 		return aas;
@@ -58,12 +75,16 @@
 
 	@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 VABMultiSubmodelProvider createMultiSubmodelProvider(AssetAdministrationShell aas) {
+		return new VABMultiSubmodelProvider(new AASModelProvider(aas), registry, new HTTPConnectorProvider());
 	}
 
 	@Override
@@ -71,7 +92,14 @@
 		aasProviderMap.remove(aasId.getId());
 	}
 
-	public VABMultiSubmodelProvider getProviderForAASId(String aasId) {
-		return aasProviderMap.get(aasId);
+	@Override
+	public IModelProvider getAASProvider(IIdentifier aasId) {
+		VABMultiSubmodelProvider 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..600014f 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
@@ -5,6 +5,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 +31,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 +53,7 @@
 	 * 
 	 * @param aas the updated AAS
 	 */
-	public void updateAAS(AssetAdministrationShell aas);
+	public void updateAAS(AssetAdministrationShell aas) throws ResourceNotFoundException;
 	
 	/**
 	 * Deletes a specific Asset Administration Shell
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..f14a1a0 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
@@ -5,12 +5,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 +30,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,7 +40,20 @@
 	 * @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) {
+		if (!url.endsWith(AASAggregatorProvider.PREFIX)) {
+			url = url + AASAggregatorProvider.PREFIX;
+		}
+		return url;
 	}
 
 	@SuppressWarnings("unchecked")
@@ -45,32 +61,60 @@
 	public Collection<IAssetAdministrationShell> getAASList() {
 		Collection<Map<String, Object>> collection = (Collection<Map<String, Object>>) provider.getModelPropertyValue("");
 		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.getModelPropertyValue("");
+		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.setModelPropertyValue(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.setModelPropertyValue(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..4b0ca6b 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,17 @@
 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,22 +23,22 @@
  *
  */
 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);
@@ -50,57 +49,57 @@
 		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 {
 		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).getModelPropertyValue(restPath);
 			}
 		}
 	}
@@ -108,28 +107,30 @@
 	@Override
 	public void setModelPropertyValue(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).setModelPropertyValue(restPath, newValue);
 			}
 		} else {
 			throw new MalformedRequestException("Set with empty path is not supported by aggregator");
@@ -139,22 +140,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 +157,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 +185,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/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..0034015
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/factory/json/JSONToMetamodelConverter.java
@@ -0,0 +1,72 @@
+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.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 parse JSON to Metamodel Objects
+ * 
+ * @author conradi
+ *
+ */
+public class JSONToMetamodelConverter {
+	
+	private Map<String, Object> root;
+	
+	@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() {
+		return ((List<Object>) root.get(MetamodelToJSONConverter.ASSET_ADMINISTRATION_SHELLS)).stream()
+				.map(i -> AssetAdministrationShell.createAsFacade((Map<String, Object>) i)).collect(Collectors.toList());
+	}
+	
+	/**
+	 * 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..59ba7a4
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/factory/json/MetamodelToJSONConverter.java
@@ -0,0 +1,64 @@
+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);
+	}	
+}
\ 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..2d2c381 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,6 +10,7 @@
 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;
@@ -21,6 +22,7 @@
 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.restapi.SubModelProvider;
 import org.eclipse.basyx.vab.exception.FeatureNotImplementedException;
 import org.eclipse.basyx.vab.factory.java.ModelProxyFactory;
 import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
@@ -64,11 +66,8 @@
 
 	@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());
+		// look up SM descriptor in the registry
+		SubmodelDescriptor smDescriptor = aasDirectory.lookupSubmodel(aasId, smId);
 
 		// get address of the submodel descriptor
 		String addr = smDescriptor.getFirstEndpoint();
@@ -78,9 +77,9 @@
 	}
 
 	@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
@@ -99,23 +98,16 @@
 	}
 
 	@Override
+	@Deprecated
 	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");
-		}
+		createAAS(aas, endpoint);
 	}
 
 	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 +120,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) {
 		
 		// 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 +154,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 = connectorProvider.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..af0cf1e 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
@@ -31,12 +31,22 @@
 	/**
 	 * Creates an AAS on a remote server.
 	 */
+	@Deprecated
 	void createAAS(AssetAdministrationShell aas, IIdentifier aasId, String endpoint);
 	
 	/**
+	 * Creates an AAS on a remote server
+	 * 
+	 * @param aas
+	 * @param aasId
+	 * @param 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
@@ -50,6 +60,14 @@
 	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);
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..6e1ebe8
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/api/IAasEnv.java
@@ -0,0 +1,18 @@
+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..78a9a21 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
@@ -9,6 +9,7 @@
 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.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;
@@ -25,7 +26,7 @@
 	/**
 	 * Return all registered submodels of this AAS
 	 * 
-	 * @return
+	 * @return IdShort -> ISubmodel
 	 */
 	public Map<String, ISubModel> getSubModels();
 
@@ -37,7 +38,7 @@
 	public Collection<IReference> getSubmodelReferences();
 
 	/**
-	 * Add a sub model to the AAS
+	 * Add a submodel to the AAS
 	 * 
 	 * @param subModel
 	 *            The added sub model
@@ -45,6 +46,20 @@
 	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.
 	 * 
 	 * @return
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..20e2fc8 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,7 +1,9 @@
 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;
@@ -22,6 +24,8 @@
 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.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;
@@ -29,29 +33,47 @@
 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
-	 * and path
 	 * 
-	 * @param path
 	 * @param proxy
 	 * @param manager
 	 */
+	@Deprecated
 	public ConnectedAssetAdministrationShell(VABElementProxy proxy, ConnectedAssetAdministrationShellManager manager) {
 		super(proxy);
-		this.manager = 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 an already cached local copy
+	 * 
+	 * @param proxy
+	 * @param localCopy
+	 */
+	public ConnectedAssetAdministrationShell(VABElementProxy proxy, AssetAdministrationShell localCopy) {
+		super(proxy);
 	}
 
 	/**
@@ -118,15 +140,28 @@
 		return set.stream().map(ConceptDictionary::createAsFacade).collect(Collectors.toSet());
 	}
 
+	@SuppressWarnings("unchecked")
 	@Override
 	public Map<String, ISubModel> getSubModels() {
-		return manager.retrieveSubmodels(getIdentification());
+		Collection<Map<String, Object>> submodelCollection = (Collection<Map<String, Object>>) getProxy().getModelPropertyValue(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) {
 		subModel.setParent(getReference());
-		getProxy().createValue("/submodels", subModel);
+		Map<String, Object> convertedMap = SubmodelElementMapCollectionConverter.smToMap(subModel);
+		String accessPath = VABPathTools.concatenatePaths(AssetAdministrationShell.SUBMODELS, subModel.getIdShort());
+		getProxy().setModelPropertyValue(accessPath, convertedMap);
 	}
 
 	@Override
@@ -169,4 +204,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/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..379e956
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/AasEnv.java
@@ -0,0 +1,148 @@
+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..3fc447c 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
@@ -35,6 +35,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;
@@ -61,7 +62,7 @@
 	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
@@ -69,6 +70,18 @@
 	public AssetAdministrationShell() {
 		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) {
@@ -289,6 +302,13 @@
 		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
 	 * 
@@ -322,7 +342,7 @@
 	private void addSubmodelReferences(SubModel submodel) {
 		addSubmodelReference(submodel.getReference());
 	}
-	
+
 	private KeyElements getKeyElement() {
 		return KeyElements.ASSETADMINISTRATIONSHELL;
 	}
@@ -342,4 +362,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..d4a6ef2 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
@@ -14,6 +14,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 +23,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 +31,10 @@
 	 */
 	public AASDescriptor(Map<String, Object> map) {
 		super(map);
+		validate(map);
+
+		// Set map again
+		putAll(map);
 	}
 
 	protected AASDescriptor() {
@@ -96,6 +101,7 @@
 		
 		// Add new sub model descriptor to list
 		submodelDescriptors.add(desc);
+		put(AssetAdministrationShell.SUBMODELS, submodelDescriptors);
 
 		// Enable method chaining
 		return this;
@@ -112,6 +118,17 @@
 		}
 	}
 
+	@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()) {
+			// Don't use getSubmodelDescriptors here since it returns a copy
+			((Collection<Object>) get(AssetAdministrationShell.SUBMODELS)).remove(toRemove.get());
+		}
+	}
+
 	/**
 	 * Retrieves a submodel descriptor based on the globally unique id of the
 	 * submodel
@@ -179,5 +196,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..6c0964b
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/descriptor/CustomId.java
@@ -0,0 +1,22 @@
+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..48b8b72 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
@@ -12,6 +12,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;
 
 /**
@@ -105,6 +106,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(AssetAdministrationShell.ENDPOINTS) || !(map.get(AssetAdministrationShell.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/SubmodelDescriptor.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/descriptor/SubmodelDescriptor.java
index 2149eda..bb272e8 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
@@ -4,8 +4,11 @@
 
 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 +19,7 @@
  * @author kuhn
  *
  */
-public class SubmodelDescriptor extends ModelDescriptor {
+public class SubmodelDescriptor extends ModelDescriptor implements IHasSemantics {
 	
 	public static final String MODELTYPE = "SubmodelDescriptor";
 
@@ -25,6 +28,7 @@
 	 */
 	public SubmodelDescriptor(Map<String, Object> map) {
 		super(map);
+		validate(map);
 	}
 	
 	/**
@@ -42,7 +46,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 +56,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..148030e 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
@@ -49,8 +49,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);
 	}
 
 	/**
@@ -122,6 +134,10 @@
 		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);
 	}
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..90e2d4f 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
@@ -36,6 +36,15 @@
 		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());
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..9ad20a4 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
@@ -45,6 +45,15 @@
 		// Default values
 		put(CONTAINEDELEMENT, new HashSet<Reference>());
 	}
+	
+	/**
+	 * Constructor accepting only mandatory attribute
+	 * @param idShort
+	 */
+	public View(String idShort) {
+		this();
+		setIdShort(idShort);
+	}
 
 	/**
 	 * 
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
index 2dc8ede..6ff18e4 100644
--- 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
@@ -36,7 +36,7 @@
 	/**
 	 * Delete SM descriptor from registry
 	 */
-	public void delete(IIdentifier aasId, String smIdShort) throws ProviderException;
+	public void delete(IIdentifier aasId, IIdentifier smId) throws ProviderException;
 	
 	/**
 	 * Lookup AAS
@@ -49,5 +49,28 @@
 	 * @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/memory/AASRegistry.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/memory/AASRegistry.java
index 6a2e7f5..1ac6c8d 100644
--- 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
@@ -1,11 +1,13 @@
 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.IAASRegistryService;
 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;
@@ -63,32 +65,60 @@
 	@Override
 	public void register(IIdentifier aas, SubmodelDescriptor smDescriptor) {
 		try {
-			delete(aas, smDescriptor.getIdShort());
+			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, String smIdShort) {
+	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.getSubmodelDescriptorFromIdShort(smIdShort) == null) {
+		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(smIdShort);
+		desc.removeSubmodelDescriptor(smId);
 		handler.update(desc);
-		logger.debug("Deleted submodel " + smIdShort + " from AAS " + aasId.getId());
+		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/proxy/AASRegistryProxy.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/proxy/AASRegistryProxy.java
index a84b403..15ace7c 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
@@ -27,7 +27,7 @@
 /**
  * Local proxy class that hides HTTP calls to BaSys registry
  * 
- * @author kuhn
+ * @author kuhn, schnicke
  *
  */
 public class AASRegistryProxy extends VABDirectoryProxy implements IAASRegistryService {
@@ -41,7 +41,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(DirectoryModelProvider.PREFIX)) {
+			url = url.substring(0, url.length() - DirectoryModelProvider.PREFIX.length());
+		}
+		return url;
 	}
 
 	/**
@@ -130,7 +143,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.setModelPropertyValue(VABPathTools.concatenatePaths(buildSubmodelPath(aas), URLEncoder.encode(smDescriptor.getIdentifier().getId(), "UTF-8")), smDescriptor);
 		} catch (Exception e) {
 			if (e instanceof ProviderException) {
 				throw (ProviderException) e;
@@ -141,9 +154,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;
@@ -158,5 +171,36 @@
 		String encodedAASId = VABPathTools.encodePathElement(aas.getId());
 		return VABPathTools.concatenatePaths(encodedAASId, DirectoryModelProvider.SUBMODELS);
 	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public List<SubmodelDescriptor> lookupSubmodels(IIdentifier aasId) throws ProviderException {
+		try {
+			Object result = provider.getModelPropertyValue(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.getModelPropertyValue(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/DirectoryModelProvider.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/restapi/DirectoryModelProvider.java
index f2072d0..fffe50d 100644
--- 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
@@ -211,7 +211,16 @@
 			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));
+				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);
@@ -246,12 +255,13 @@
 			ModelUrn aasId = retrieveModelURN(splitted[0]);
 			
 			SubmodelDescriptor smDescriptor = createSMDescriptorFromMap(newEntity);
+			String smId = smDescriptor.getIdentifier().getId();
 			
 			//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() +
+				getSmDescriptorFromAAS(aasId, smId);
+				throw new ResourceAlreadyExistsException("A Submodel with id '" + smId +
 						"' already exists in aas '" + splitted[0] + "'. Try update instead.");
 			} catch (ResourceNotFoundException e) {
 				registry.register(aasId, smDescriptor);
@@ -285,11 +295,12 @@
 			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) {
+			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, smId);
+			registry.delete(aasId, smDesc.getIdentifier());
 		} else {
 			throw new MalformedRequestException("Delete with empty path is not supported by registry");
 		}
@@ -337,7 +348,7 @@
 			throw new ResourceNotFoundException("Specified AASId '" + aasId.getId() + "' does not exist.");
 		}
 		
-		SubmodelDescriptor smDescriptor = aasDescriptor.getSubmodelDescriptorFromIdShort(smId);
+		SubmodelDescriptor smDescriptor = aasDescriptor.getSubModelDescriptorFromIdentifierId(smId);
 		if (smDescriptor == null) {
 			throw new ResourceNotFoundException("Specified SMId '" + smId + "' for AAS " + aasId.getId() + " does not exist.");
 		}
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
index 2ae86be..879c230 100644
--- 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
@@ -2,7 +2,9 @@
 
 import java.util.HashMap;
 
+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;
 
@@ -43,81 +45,67 @@
 	@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);
+		VABMultiSubmodelProvider provider = aas_providers.get(aasId);
+		if (provider == null) {
+			throw new ResourceNotFoundException("AAS with ID \"" + aasId + "\" does not exist.");
 		}
-		return null;
+		String subPath = getSubPath(path, aasId);
+		return provider.getModelPropertyValue(subPath);
 	}
 
 	@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);
+		VABMultiSubmodelProvider provider = aas_providers.get(aasId);
+		if (provider == null) {
+			throw new ResourceNotFoundException("AAS with ID \"" + aasId + "\" does not exist.");
 		}
+		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);
+		VABMultiSubmodelProvider provider = aas_providers.get(aasId);
+		if (provider == null) {
+			throw new ResourceNotFoundException("AAS with ID \"" + aasId + "\" does not exist.");
 		}
+		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);
+		VABMultiSubmodelProvider provider = aas_providers.get(aasId);
+		if (provider == null) {
+			throw new ResourceNotFoundException("AAS with ID \"" + aasId + "\" does not exist.");
 		}
+		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);
+		VABMultiSubmodelProvider provider = aas_providers.get(aasId);
+		if (provider == null) {
+			throw new ResourceNotFoundException("AAS with ID \"" + aasId + "\" does not exist.");
 		}
+		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);
+		VABMultiSubmodelProvider provider = aas_providers.get(aasId);
+		if (provider == null) {
+			throw new ResourceNotFoundException("AAS with ID \"" + aasId + "\" does not exist.");
 		}
-		return null;
+		String subPath = getSubPath(path, aasId);
+		return provider.invokeOperation(subPath, parameter);
 	}
 
 	/**
@@ -131,7 +119,7 @@
 	 */
 	private String getId(String path) {
 		if (path == null) {
-			return null;
+			throw new MalformedRequestException("No AASId specified.");
 		}
 
 		String[] elements = VABPathTools.splitPath(path);
@@ -139,7 +127,7 @@
 			String aasId = elements[0];
 			return aasId;
 		} else {
-			return null;
+			throw new MalformedRequestException("No AASId specified.");
 		}
 	}
 
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
index c4a401a..02cf8d9 100644
--- 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
@@ -3,15 +3,24 @@
 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.IAASRegistryService;
+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.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.IConnectorProvider;
+import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorProvider;
 
 /**
  * Provider class that implements the AssetAdministrationShellServices <br />
@@ -75,11 +84,26 @@
 	 * 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 IAASRegistryService registry = null;
+	
+	/**
+	 * Store HTTP Connector
+	 */
+	protected IConnectorProvider connectorProvider = null;
 
 	/**
 	 * Constructor
@@ -104,6 +128,29 @@
 		// Store content provider
 		addSubmodel(smID, contentProvider);
 	}
+	
+	/**
+	 * Constructor that accepts a registry and a connection provider
+	 * @param registry
+	 * @param provider
+	 */
+	public VABMultiSubmodelProvider(IAASRegistryService registry, IConnectorProvider provider) {
+		this();
+		this.registry = registry;
+		this.connectorProvider = provider;
+	}
+	
+	/**
+	 * Constructor that accepts a aas provider, a registry and a connection provider
+	 * @param contentProvider
+	 * @param registry
+	 * @param provider
+	 */
+	public VABMultiSubmodelProvider(AASModelProvider contentProvider, IAASRegistryService registry, HTTPConnectorProvider provider) {
+		this(contentProvider);
+		this.registry = registry;
+		this.connectorProvider = provider;
+	}
 
 	/**
 	 * Set an AAS for this provider
@@ -113,9 +160,11 @@
 	 * @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.getModelPropertyValue("")).getIdentification();
 	}
 
 	/**
@@ -127,6 +176,7 @@
 	 *            Model content provider
 	 */
 	@SuppressWarnings("unchecked")
+	@Deprecated
 	public void addSubmodel(String elementId, SubModelProvider modelContentProvider) {
 		// Add model provider
 		submodel_providers.put(elementId, modelContentProvider);
@@ -137,6 +187,15 @@
 		aas_provider.createValue("/submodels", sm);
 	}
 
+	@SuppressWarnings("unchecked")
+	public void addSubmodel(SubModelProvider modelContentProvider) {
+		SubModel sm = SubModel.createAsFacade((Map<String, Object>) modelContentProvider.getModelPropertyValue("/"));
+		submodel_providers.put(sm.getIdShort(), modelContentProvider);
+
+		// Adds a new submodel to the registered AAS
+		aas_provider.createValue("/submodels", sm);
+	}
+
 	/**
 	 * Remove a provider
 	 * 
@@ -154,75 +213,104 @@
 	@Override
 	public Object getModelPropertyValue(String path) throws ProviderException {
 		VABPathTools.checkPathForNull(path);
+		path = VABPathTools.stripSlashes(path);
 		String[] pathElements = VABPathTools.splitPath(path);
-		if (pathElements.length == 0) { // e.g. "/"
-			return null;
-		} else if (pathElements[0].equals("aas")) {
+		if (pathElements.length > 0 && 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;
+					return retrieveSubmodels();
 				} else {
-					IModelProvider hashmapProvider = submodel_providers.get(pathElements[2]);
+					IModelProvider provider = submodel_providers.get(pathElements[2]);
 
-					if(hashmapProvider == null) {
-						throw new ResourceNotFoundException("Submodel with id " + pathElements[2] + " does not exist");
+					if (provider == null) {
+						// Get a model provider for the submodel in the registry
+						provider = getModelProvider(pathElements[2]);
 					}
 					
 					// - Retrieve submodel or property value
-					return hashmapProvider.getModelPropertyValue(VABPathTools.buildPath(pathElements, 3));
+					return provider.getModelPropertyValue(VABPathTools.buildPath(pathElements, 4));
 				}
 			} else {
 				// Handle access to AAS
 				return aas_provider.getModelPropertyValue(VABPathTools.buildPath(pathElements, 1));
 			}
 		} else {
-			return null;
+			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.getModelPropertyValue("")));
+		}
+
+		// Check for remote submodels
+		if (registry != null) {
+			AASDescriptor desc = registry.lookupAAS(aasId);
+			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<SubModel> remoteSms = missingIds.stream().map(id -> desc.getSubModelDescriptorFromIdentifierId(id.getId())).
+						map(smDesc -> smDesc.getFirstEndpoint()).map(endpoint -> connectorProvider.getConnector(endpoint)).
+						map(p -> (Map<String, Object>) p.getModelPropertyValue("")).map(m -> SubModel.createAsFacade(m)).collect(Collectors.toList());
+				submodels.addAll(remoteSms);
+			}
+		}
+
+		return submodels;
+	}
+
+	/**
 	 * Change a model property value
 	 */
 	@Override
 	public void setModelPropertyValue(String path, Object newValue) throws ProviderException {
-		VABPathTools.checkPathForNull(path);
+ 		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'
-		submodel_providers.get(pathElements[2]).setModelPropertyValue(propertyPath, newValue);
+		
+		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);
+		}
+
+		IModelProvider provider;
+		try {
+			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.setModelPropertyValue(propertyPath, newValue);
+		} catch (ResourceNotFoundException e) {
+			createSubModel(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);
-				}
-			}
-		}
+		throw new MalformedRequestException("Create is not supported by VABMultiSubmodelProvider. Path was: " + path);
 	}
 
-	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) {
@@ -235,7 +323,7 @@
 		// Adds a new submodel to the registered AAS
 		SubModel sm = SubModel.createAsFacade((Map<String, Object>) newSM);
 
-		addSubmodel(sm.getIdShort(), new SubModelProvider(sm));
+		addSubmodel(new SubModelProvider(sm));
 	}
 
 
@@ -243,14 +331,15 @@
 	@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 (!submodel_providers.containsKey(smIdShort)) {
-				return;
+			if (!isSubmodelLocal(smIdShort)) {
+				return;	
 			}
 
 			// Delete submodel reference from aas
@@ -261,26 +350,99 @@
 			// Remove submodel provider
 			submodel_providers.remove(smIdShort);
 		} else if (propertyPath.length() > 0) {
-			submodel_providers.get(pathElements[2]).deleteValue(propertyPath);
+			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 {
-		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);
+		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
-		return submodel_providers.get(pathElements[2]).invokeOperation(operationPath, parameter);
+		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 connectorProvider.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);
 	}
 }
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..a0dc960 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
@@ -17,6 +17,7 @@
 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.valuetypedef.PropertyValueTypeDefHelper;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 
@@ -50,7 +51,7 @@
 		//The IQualifiable object has to be treated as Map here, as the Interface has no Setters
 		
 		Map<String, Object> qualifierObj = (Map<String, Object>) xmlObject.get(QUALIFIER);
-		qualifiable.put(Qualifiable.CONSTRAINTS, parseConstraints(qualifierObj));
+		qualifiable.put(Qualifiable.QUALIFIERS, parseConstraints(qualifierObj));
 	}
 	
 	
@@ -126,7 +127,7 @@
 		qualifier.setType(type);
 		qualifier.setValue(value);
 		qualifier.setValueId(ref);
-		qualifier.setValueType(valueType);
+		qualifier.setValueType(PropertyValueTypeDefHelper.fromName(valueType));
 		
 		return qualifier;
 	}
@@ -143,10 +144,10 @@
 	 * @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);
 		
@@ -209,7 +210,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/submodelelement/SubmodelElementCollectionXMLConverter.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/SubmodelElementCollectionXMLConverter.java
index 38cfc77..af6f74d 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
@@ -67,7 +67,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..5b3bf55 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
@@ -38,9 +38,9 @@
 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;
@@ -50,7 +50,7 @@
 
 /**
  * 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
  *
@@ -61,6 +61,7 @@
 	public static final String SUBMODEL_ELEMENT = "aas:submodelElement";
 	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 +69,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 +79,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,7 +101,7 @@
 	 * 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) {
@@ -191,7 +192,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
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..d8f3dff 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
@@ -15,7 +15,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 +23,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..f44b4b8 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
@@ -3,8 +3,11 @@
 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.slf4j.Logger;
@@ -14,7 +17,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,6 +35,7 @@
 	 * @param xmlObject the Map with the content of XML tag &lt;aas:property&gt;
 	 * @return the parsed Property
 	 */
+	@SuppressWarnings("unchecked")
 	public static Property parsePropery(Map<String, Object> xmlObject) {
 		
 		Property property = new Property();
@@ -41,9 +45,15 @@
 		String valueType = XMLHelper.getString(xmlObject.get(SubmodelElementXMLConverter.VALUE_TYPE));
 		String value = XMLHelper.getString(xmlObject.get(SubmodelElementXMLConverter.VALUE));
 		
+		Map<String, Object> xmlValueId = (Map<String, Object>) xmlObject.get(VALUE_ID);
+		Reference valueId = ReferenceXMLConverter.parseReference(xmlValueId);
+		
 		property.set(value, PropertyValueTypeDefHelper.fromName(valueType));
 		
-		//FIXME the XML-ELement valueId has no corresponding field in Property
+		if(valueId != null) {
+			property.setValueId(valueId);
+		}
+		
 		return property;
 	}
 	
@@ -62,12 +72,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 +95,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));
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..6580fa7 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
@@ -5,7 +5,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.valuetypedef.PropertyValueTypeDefHelper;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.range.Range;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 
@@ -33,7 +34,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(PropertyValueTypeDefHelper.fromName(valueType), min, max);
 		populateSubmodelElement(xmlObject, range);
 		return range;
 	}
@@ -68,7 +69,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/metamodel/api/IElementContainer.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/IElementContainer.java
index 093e1b2..8e72294 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
@@ -41,4 +41,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
index 2f716ab..2ab51af 100644
--- 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
@@ -1,5 +1,7 @@
 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;
@@ -20,4 +22,12 @@
  *
  */
 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/qualifier/qualifiable/IQualifiable.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/qualifiable/IQualifiable.java
index 28b33f7..302d175 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
@@ -9,5 +9,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..143667d 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
@@ -2,6 +2,7 @@
 
 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.valuetypedef.PropertyValueTypeDef;
 
 /**
  * Interface for Qualifier
@@ -13,9 +14,9 @@
 public interface IQualifier extends IHasSemantics, IConstraint {
 	public String getType();
 
-	public String getValue();
+	public Object getValue();
 
 	public IReference getValueId();
 	
-	public String getValueType();
+	public PropertyValueTypeDef  getValueType();
 }
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..542be10 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
@@ -16,4 +16,8 @@
  */
 public interface ISubmodelElement extends IElement, IHasDataSpecification, IReferable, IQualifiable, IHasSemantics, IHasKind {
 	public String getModelType();
+	
+	public Object getValue();
+	
+	public void setValue(Object value);
 }
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..ef185cd 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,8 @@
 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 +12,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 +33,7 @@
 	 * 
 	 * @return
 	 */
+	@Override
 	public Map<String, ISubmodelElement> getSubmodelElements();
 
 	/**
@@ -42,6 +41,7 @@
 	 * 
 	 * @return
 	 */
+	@Override
 	public Map<String, IProperty> getProperties();
 
 	/**
@@ -49,5 +49,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/dataelement/IProperty.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IProperty.java
index 20d1381..71d91a7 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
@@ -2,6 +2,7 @@
 
 import org.eclipse.basyx.submodel.metamodel.api.IElement;
 import org.eclipse.basyx.submodel.metamodel.api.reference.IReference;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetypedef.PropertyValueTypeDef;
 import org.eclipse.basyx.vab.exception.provider.ProviderException;
 
 /**
@@ -12,11 +13,13 @@
  */
 public interface IProperty extends IElement, IDataElement {
 	/**
+	 * Will be replaced by getValue()
 	 * Get property value
 	 * 
 	 * @return Property value
 	 * @throws Exception
 	 */
+	@Deprecated
 	public Object get() throws Exception;
 
 	/**
@@ -31,7 +34,7 @@
 	 * 
 	 * @return
 	 */
-	public String getValueType();
+	public PropertyValueTypeDef 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..f9f4015 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,7 @@
 package org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement;
 
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetypedef.PropertyValueTypeDef;
+
 /**
  * A range data element is a data element that defines a range with min and max.
  * 
@@ -12,7 +14,7 @@
 	 * 
 	 * @return
 	 */
-	String getValueType();
+	PropertyValueTypeDef getValueType();
 
 	/**
 	 * Returns the minimum value of the range. <br />
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..3f1c95b
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/operation/IAsyncInvocation.java
@@ -0,0 +1,26 @@
+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..98b56d6 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
@@ -43,4 +43,13 @@
 	 * @throws Exception
 	 */
 	public Object invoke(Object... params) throws Exception;
+	
+	/**
+	 * Invoke operation with given parameter asynchronously
+	 * 
+	 * @param params
+	 *            Operation parameter
+	 * @return An IAsyncInvocation
+	 */
+	public IAsyncInvocation invokeAsync(Object... params);
 }
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..fc4964e 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
@@ -16,7 +16,7 @@
 public class ConnectedElement implements IElement {
 
 	private VABElementProxy proxy;
-	private VABModelMap<Object> cached;
+	protected VABModelMap<Object> cached;
 
 	public VABElementProxy getProxy() {
 		return proxy;
@@ -57,6 +57,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
index 5d0a57a..b1a56b3 100644
--- 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
@@ -12,11 +12,11 @@
 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.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;
@@ -24,10 +24,12 @@
 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.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;
 
 
 /**
@@ -42,19 +44,29 @@
 		super(proxy);
 	}
 
-	protected KeyElements getKeyElement() {
-		return KeyElements.SUBMODELELEMENT;
+	/**
+	 * 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;
 	}
 
-	@SuppressWarnings("unchecked")
+	protected KeyElements getKeyElement() {
+		return KeyElements.SUBMODEL;
+	}
+
 	@Override
 	public IReference getSemanticId() {
-		return Reference.createAsFacade((Map<String, Object>) getElem().get(HasSemantics.SEMANTICID));
+		return HasSemantics.createAsFacade(getElem()).getSemanticId();
 	}
 
 	@Override
 	public IAdministrativeInformation getAdministration() {
-		return AdministrativeInformation.createAsFacade(getElem());
+		return Identifiable.createAsFacade(getElem(), getKeyElement()).getAdministration();
 	}
 
 	@Override
@@ -92,52 +104,94 @@
 		return Referable.createAsFacade(getElem(), getKeyElement()).getDescription();
 	}
 
-	@SuppressWarnings("unchecked")
 	@Override
 	public IReference getParent() {
-		return Reference.createAsFacade((Map<String, Object>) getElem().getPath(Referable.PARENT));
+		return Referable.createAsFacade(getElem(), getKeyElement()).getParent();
 	}
 	
 	@Override
-	public Collection<IConstraint> getQualifier() {
-		return Qualifiable.createAsFacade(getElem()).getQualifier();
+	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().setModelPropertyValue(path, converted);
+				return;
+			}
 		}
-		
-		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);
-		}
+		getProxy().setModelPropertyValue(path, element);
 	}
 
 	@Override
 	public Map<String, IProperty> getProperties() {
-		return ConnectedSubmodelElementFactory.getProperties(getProxy(), SubmodelElementProvider.PROPERTIES,
-						SubmodelElementProvider.PROPERTIES);
+		return ConnectedSubmodelElementFactory.getProperties(getProxy(), MultiSubmodelElementProvider.ELEMENTS,
+						MultiSubmodelElementProvider.ELEMENTS);
 	}
 
 	@Override
 	public Map<String, IOperation> getOperations() {
-		return ConnectedSubmodelElementFactory.getOperations(getProxy(), SubmodelElementProvider.OPERATIONS,
-				SubmodelElementProvider.OPERATIONS);
+		return ConnectedSubmodelElementFactory.getOperations(getProxy(), MultiSubmodelElementProvider.ELEMENTS,
+				MultiSubmodelElementProvider.ELEMENTS);
 	}
 
 	@Override
 	public Map<String, ISubmodelElement> getSubmodelElements() {
 		return ConnectedSubmodelElementFactory.getConnectedSubmodelElements(getProxy(),
-				SubmodelElementProvider.ELEMENTS, SubmodelElementProvider.ELEMENTS);
+				MultiSubmodelElementProvider.ELEMENTS, MultiSubmodelElementProvider.ELEMENTS);
+	}
+	
+	@SuppressWarnings("unchecked")
+	@Override
+	public Map<String, Object> getValues() {
+		return (Map<String, Object>) getProxy().getModelPropertyValue(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().getModelPropertyValue(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/ConnectedSubmodelElement.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/ConnectedSubmodelElement.java
index a56d67e..e5b2318 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
@@ -17,6 +17,7 @@
 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.restapi.MultiSubmodelElementProvider;
 import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
 
 /**
@@ -54,8 +55,8 @@
 	}
 
 	@Override
-	public Collection<IConstraint> getQualifier() {
-		return Qualifiable.createAsFacade(getElem()).getQualifier();
+	public Collection<IConstraint> getQualifiers() {
+		return Qualifiable.createAsFacade(getElem()).getQualifiers();
 	}
 
 	@Override
@@ -89,4 +90,9 @@
 	public IReference getReference() {
 		return Referable.createAsFacade(getElem(), getKeyElement()).getReference();
 	}
+	
+	@Override
+	public void setValue(Object value) {
+		getProxy().setModelPropertyValue(MultiSubmodelElementProvider.VALUE, value);
+	}
 }
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..6ebc44e 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,5 @@
 package org.eclipse.basyx.submodel.metamodel.connected.submodelelement;
 
-import java.util.Collection;
 import java.util.Map;
 
 import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
@@ -8,6 +7,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 +25,8 @@
 	}
 
 	@Override
-	public Collection<ISubmodelElement> getValue() {
-		return getSubmodelElements().values();
+	public Map<String, ISubmodelElement> getValue() {
+		return getSubmodelElements();
 	}
 
 	@Override
@@ -57,4 +58,47 @@
 	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().getModelPropertyValue(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().setModelPropertyValue(element.getIdShort(), converted);
+				return;
+			}
+		}
+		
+		getProxy().setModelPropertyValue(element.getIdShort(), element);
+	}
 }
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..f74e68e 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
@@ -25,9 +25,9 @@
 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;
@@ -99,7 +99,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);
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..c5b4f5c 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,7 +1,5 @@
 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.IBlob;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.Blob;
@@ -19,13 +17,11 @@
 		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();
+		return (byte[]) getProxy().getModelPropertyValue(Property.VALUE);
 	}
 
 	@Override
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..b2210ec 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
@@ -20,4 +20,9 @@
 	protected KeyElements getKeyElement() {
 		return KeyElements.DATAELEMENT;
 	}
+	
+	@Override
+	public Object getValue() {
+		throw new UnsupportedOperationException("getValue is only possible in specific Element");
+	}
 }
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..83768af 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,5 @@
 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 +17,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().getModelPropertyValue(Property.VALUE);
 	}
 
 	@Override
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..28d81f5 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
@@ -6,8 +6,8 @@
 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.PropertyValueTypeDef;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetypedef.PropertyValueTypeDefHelper;
 import org.eclipse.basyx.vab.exception.provider.ProviderException;
 import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
@@ -27,30 +27,28 @@
 
 	@Override
 	public Object get() throws Exception {
-		return retrieveObject();
+		return getValue();
 	}
 
 	@Override
 	public void set(Object newValue) throws ProviderException {
-		getProxy().setModelPropertyValue(Property.VALUE, newValue);
+		getProxy().setModelPropertyValue(Property.VALUE, PropertyValueTypeDefHelper.prepareForSerialization(newValue));
 	}
 
-	@SuppressWarnings({ "unchecked" })
 	@Override
-	public String getValueType() {
-		Object o = getProxy().getModelPropertyValue("");
-		return PropertyValueTypeDefHelper.readTypeDef(((Map<String, Object>) o).get(Property.VALUETYPE)).toString();
+	public PropertyValueTypeDef getValueType() {
+		return PropertyValueTypeDefHelper.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>) getProxy().getModelPropertyValue(Property.VALUEID));
 	}
 
 	@SuppressWarnings("unchecked")
 	protected <T> T retrieveObject() {
-		return (T) ((Map<String, Object>) getProxy().getModelPropertyValue(Property.VALUE)).get(Property.VALUE);
+		return (T) getProxy().getModelPropertyValue(Property.VALUE);
 	}
 	
 	@Override
@@ -58,4 +56,19 @@
 		return KeyElements.PROPERTY;
 	}
 
+	@Override
+	public Object getValue() {
+		Object value =  retrieveObject();
+		if(value instanceof String) {
+			return PropertyValueTypeDefHelper.getJavaObject(value, getValueType());
+		}else {
+			return value;
+		}
+	}
+	
+	@Override
+	public void setValue(Object value) {
+		this.set(value);
+	}
+
 }
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..4e8bf61 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,14 @@
 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.valuetypedef.PropertyValueTypeDef;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetypedef.PropertyValueTypeDefHelper;
+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 +23,49 @@
 	}
 
 	@Override
-	public String getValueType() {
-		return (String) getElem().getPath(Range.VALUETYPE);
+	public PropertyValueTypeDef getValueType() {
+		return PropertyValueTypeDefHelper.readTypeDef(getElem().getPath(Range.VALUETYPE));
 	}
 
 	@Override
 	public Object getMin() {
-		return getElem().getPath(Range.MIN);
+		Object min = getElem().getPath(Range.MIN);
+		return PropertyValueTypeDefHelper.getJavaObject(min, getValueType());
 	}
 
 	@Override
 	public Object getMax() {
-		return getElem().getPath(Range.MAX);
+		Object max = getElem().getPath(Range.MAX);
+		return PropertyValueTypeDefHelper.getJavaObject(max, getValueType());
 	}
 
 	@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 rangeValue = RangeValue.createAsFacade((Map<String, Object>) value);
+			Object minRaw = rangeValue.getMin();
+			Object maxRaw = rangeValue.getMax();
+
+			RangeValue prepared = new RangeValue(
+					PropertyValueTypeDefHelper.prepareForSerialization(minRaw),
+					PropertyValueTypeDefHelper.prepareForSerialization(maxRaw)
+				);
+					
+			
+			getProxy().setModelPropertyValue(MultiSubmodelElementProvider.VALUE, prepared);
+		} else {
+			throw new IllegalArgumentException("Given object " + value + " is not a RangeValue");
+		}
+	}
 }
\ No newline at end of file
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..e3def17 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
@@ -31,4 +31,9 @@
 	protected KeyElements getKeyElement() {
 		return KeyElements.BASICEVENT;
 	}
+
+	@Override
+	public IReference getValue() {
+		return getObserved();
+	}
 }
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..69393bf
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/operation/ConnectedAsyncInvocation.java
@@ -0,0 +1,111 @@
+package org.eclipse.basyx.submodel.metamodel.connected.submodelelement.operation;
+
+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.restapi.OperationProvider;
+import org.eclipse.basyx.submodel.restapi.operation.OperationResult;
+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;
+	
+	public ConnectedAsyncInvocation(VABElementProxy proxy, String operationId, Object... parameters) {
+		this.proxy = proxy;
+		this.operationId = operationId;
+		requestId = (String) proxy.invokeOperation(Operation.INVOKE + OperationProvider.ASYNC, parameters);
+	}
+	
+	@Override
+	public Object getResult() {
+		
+		// Wait for Operation to finish
+		while(!isFinished()) {
+			try {
+				Thread.sleep(50);
+			} catch (InterruptedException e) {
+			}
+		}
+		
+		if(!resultRetrieved) {
+			// If the result was not already retrieved, do it now
+			
+			try {
+				result = proxy.getModelPropertyValue(getListPath());
+			} catch (Exception e) {
+				// Save the Exception as result for later handling
+				result = e;
+			}
+		}
+		
+		if(result instanceof Exception || result.equals(OperationResult.EXECUTION_ERROR.toString())) {
+			throw new OperationExecutionErrorException("Exception while executing Invocation '"
+					+ requestId + "' of Operation '" + operationId + "'");
+		} else {
+			return result;
+		}
+		
+	}
+	
+	@Override
+	public boolean isFinished() {
+		
+		if(resultRetrieved) {
+			// If the result was already retrieved the Operation is done
+			return true;
+		}
+		
+		try {
+			 result = proxy.getModelPropertyValue(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;
+				return true;
+			} else {
+				// If it is something else -> rethrow it
+				throw e;
+			}
+		}
+		
+		if(result.equals(OperationResult.EXECUTION_NOT_YET_FINISHED.toString())) {
+			return false;
+		}
+		
+		resultRetrieved = true;
+		return true;
+	}
+
+	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..21d7141 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
@@ -43,26 +43,56 @@
 	/**
 	 * Invoke a remote operation TODO C# includes idShort
 	 */
-	@SuppressWarnings("unchecked")
 	@Override
 	public Object invoke(Object... params) throws Exception {
 
+		// Invoke operation passing an empty string, since the used proxy already points
+		// to the operation
+		Object result = getProxy().invokeOperation(Operation.INVOKE, wrapParameters(params));
+
+		return unwrapResult(result);
+	}
+	
+	@Override
+	public ConnectedAsyncInvocation invokeAsync(Object... params) {
+		ConnectedAsyncInvocation invocation =
+				new ConnectedAsyncInvocation(getProxy(), getIdShort(), wrapParameters(params));
+		return invocation;
+	}
+	
+	@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");
+	}
+	
+	private Object[] wrapParameters(Object[] parameters) {
+		Object[] result = new Object[parameters.length];
+		
 		// Wrap parameter with valuetype information
 		int i = 0;
-		for (Object param : params) {
+		for (Object param : parameters) {
 			HashMap<String, Object> valueWrapper = new HashMap<>();
 			valueWrapper.put(Property.VALUETYPE, PropertyValueTypeDefHelper.getTypeWrapperFromObject(param));
 			valueWrapper.put(Property.VALUE, param);
 
-			params[i] = valueWrapper;
+			result[i] = valueWrapper;
 			i++;
 		}
-
-		// Invoke operation passing an empty string, since the used proxy already points
-		// to the operation
-		Object result = getProxy().invokeOperation("", params);
-
-		// Unwrap result value
+		return result;
+	}
+	
+	@SuppressWarnings("unchecked")
+	private Object unwrapResult(Object result) {
 		if (result instanceof Collection<?>) {
 			Collection<Object> coll = (Collection<Object>) result;
 			if (coll.isEmpty()) {
@@ -72,16 +102,10 @@
 			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);
 				}
 			}
 		}
-
 		return result;
 	}
-	
-	@Override
-	protected KeyElements getKeyElement() {
-		return KeyElements.OPERATION;
-	}
 }
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..05b3271 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
@@ -8,6 +8,7 @@
 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.relationship.RelationshipElement;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.relationship.RelationshipElementValue;
 import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
 
 /**
@@ -47,4 +48,9 @@
 	protected KeyElements getKeyElement() {
 		return KeyElements.RELATIONSHIPELEMENT;
 	}
+	
+	@Override
+	public RelationshipElementValue getValue() {
+		return new RelationshipElementValue(getFirst(), getSecond());
+	}
 }
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..5599c61
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/facade/SubmodelElementMapCollectionConverter.java
@@ -0,0 +1,188 @@
+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;
+	}
+	
+}
\ No newline at end of file
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..01f09ab
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/facade/SubmodelValuesHelper.java
@@ -0,0 +1,56 @@
+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;
+
+/**
+ * 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) {
+		if(value instanceof Collection<?>) {
+			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..ca0984a 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
@@ -3,14 +3,13 @@
 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;
@@ -31,34 +30,32 @@
 	 * @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 (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");
 		}
 	}
+
 	
 }
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
index 93c3f8b..0d0fd0e 100644
--- 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
@@ -20,7 +20,9 @@
 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.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;
@@ -58,9 +60,6 @@
 	 * Constructor
 	 */
 	public SubModel() {
-		// Add model type
-		putAll(new ModelType(MODELTYPE));
-
 		// Add qualifiers
 		putAll(new HasSemantics());
 		putAll(new Identifiable());
@@ -68,8 +67,23 @@
 		putAll(new HasDataSpecification());
 		putAll(new HasKind());
 
-		// Attributes
+		// 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);
 	}
 
 
@@ -78,6 +92,7 @@
 	 */
 	public SubModel(HasSemantics semantics, Identifiable identifiable, Qualifiable qualifiable,
 			HasDataSpecification specification, HasKind hasKind) {
+		this();
 		// Add qualifiers
 		putAll(semantics);
 		putAll(identifiable);
@@ -107,41 +122,12 @@
 	}
 
 
-	@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;
+		return SubmodelElementMapCollectionConverter.mapToSM(map);
 	}
 
 	@Override
@@ -167,6 +153,10 @@
 		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);
 	}
@@ -299,13 +289,44 @@
 	public Map<String, ISubmodelElement> getSubmodelElements() {
 		return (Map<String, ISubmodelElement>) get(SUBMODELELEMENT);
 	}
+
 	@Override
-	public Collection<IConstraint> getQualifier() {
-		return Qualifiable.createAsFacade(this).getQualifier();
+	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/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..6c82e2e
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/helper/ElementContainerHelper.java
@@ -0,0 +1,29 @@
+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/parts/ConceptDescription.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/parts/ConceptDescription.java
index 986e30c..daa41e0 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
@@ -42,6 +42,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
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..6ec650b 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
@@ -33,6 +33,17 @@
 		// 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());
+		setAdministration(new AdministrativeInformation());
+	}
 
 	/**
 	 * Constructor that accepts values for most relevant properties
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..543fe04 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
@@ -12,7 +12,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 +44,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..3bdcee2 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
@@ -65,6 +65,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);
+	}
 
 	/**
 	 * 
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..646e008 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
@@ -48,6 +48,14 @@
 		// Reference to the parent of this element (Referable)
 		put(PARENT, null);
 	}
+	
+	/**
+	 * Constructor with mandatory attribute
+	 * @param idShort
+	 */
+	public Referable(String idShort) {
+		setIdShort(idShort);
+	}
 
 	/**
 	 * Constructor with idShort, category and description
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..678601b 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
@@ -16,7 +16,7 @@
  *
  */
 public class Qualifiable extends VABModelMap<Object> implements IQualifiable {
-	public static final String CONSTRAINTS = "constraints";
+	public static final String QUALIFIERS = "qualifiers";
 
 	/**
 	 * Constructor
@@ -24,7 +24,7 @@
 	public Qualifiable() {
 		// The instance of an element may be further qualified by one or more
 		// qualifiers.
-		put(CONSTRAINTS, null);
+		put(QUALIFIERS, null);
 	}
 
 	/**
@@ -38,16 +38,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 +67,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..8bbb38e 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
@@ -7,6 +7,8 @@
 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.valuetypedef.PropertyValueTypeDef;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetypedef.PropertyValueTypeDefHelper;
 
 /**
  * Qualifier class
@@ -41,7 +43,16 @@
 		put(TYPE, "");
 		put(VALUE, null);
 		put(VALUEID, null);
-		put(VALUETYPE, "");
+		put(VALUETYPE, null);
+	}
+	
+	/**
+	 * 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) {
@@ -50,9 +61,9 @@
 
 		// Default values
 		put(TYPE,type);
-		put(VALUE, value);
+		put(VALUE, PropertyValueTypeDefHelper.prepareForSerialization(value));
 		put(VALUEID, valueId);
-		put(VALUETYPE, valueType);
+		put(VALUETYPE, PropertyValueTypeDefHelper.getWrapper(PropertyValueTypeDefHelper.fromName(valueType)));
 	}
 
 	/**
@@ -81,13 +92,22 @@
 		return (String) get(Qualifier.TYPE);
 	}
 
-	public void setValue(String obj) {
-		put(Qualifier.VALUE, obj);
+	public void setValue(Object obj) {
+		put(Qualifier.VALUE, PropertyValueTypeDefHelper.prepareForSerialization(obj));
+		// Value type is only set if it is not set before
+		if(getValueType() == null) {
+			put(Qualifier.VALUETYPE, PropertyValueTypeDefHelper.getTypeWrapperFromObject(obj));
+		}
 	}
 
 	@Override
-	public String getValue() {
-		return (String) get(Qualifier.VALUE);
+	public Object getValue() {
+		Object value = get(Qualifier.VALUE);
+		if(value instanceof String) {
+			return PropertyValueTypeDefHelper.getJavaObject(value, getValueType());
+		}else {
+			return value;
+		}
 	}
 
 	public void setValueId(IReference obj) {
@@ -100,13 +120,13 @@
 		return Reference.createAsFacade((Map<String, Object>) get(Qualifier.VALUEID));
 	}
 
-	public void setValueType(String obj) {
-		put(Qualifier.VALUETYPE, obj);
+	public void setValueType(PropertyValueTypeDef obj) {
+		put(Qualifier.VALUETYPE, PropertyValueTypeDefHelper.getWrapper(obj));
 	}
 	
 	@Override
-	public String getValueType() {
-		return (String) get(Qualifier.VALUETYPE);
+	public PropertyValueTypeDef getValueType() {
+		return PropertyValueTypeDefHelper.readTypeDef(get(Qualifier.VALUETYPE));
 	}
 
 	@Override
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..38fdd97 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
@@ -79,6 +79,31 @@
 		ret.setMap(map);
 		return ret;
 	}
+	
+	@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..265e94f 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
@@ -92,6 +92,21 @@
 		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/submodelelement/SubmodelElement.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/SubmodelElement.java
index f1a81bb..c01628d 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
@@ -31,12 +31,16 @@
 	protected SubmodelElement() {
 		// Add model type
 		putAll(new ModelType(MODELTYPE));
-
-		putAll(new HasDataSpecification());
-		putAll(new Referable());
-		putAll(new Qualifiable());
-		putAll(new HasSemantics());
-		putAll(new HasKind());
+		setModelingKind(ModelingKind.INSTANCE);
+	}
+	
+	/**
+	 * Constructor with only mandatory attribute
+	 * @param idShort
+	 */
+	protected SubmodelElement(String idShort) {
+		this();
+		setIdShort(idShort);
 	}
 	
 	/**
@@ -109,13 +113,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
@@ -146,4 +150,14 @@
 	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");
+	}
 }
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..10d1978 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
@@ -3,16 +3,17 @@
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
-import java.util.List;
 import java.util.Map;
 
+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 +28,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 +42,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 +79,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 +91,11 @@
 	 * @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;
+		}
+
+		return SubmodelElementMapCollectionConverter.mapToSmECollection(obj);
 	}
 	
 	/**
@@ -86,8 +104,21 @@
 	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)));
+	}
+		
+	/**
+	 * Adds an element to the SubmodelElementCollection
+	 * @param elem
+	 * 
+	 * @deprecated
+	 * This method is deprecated. Use addSubModelElement instead
+	 * which does the same work
+	 */
+	@Deprecated
+	public void addElement(ISubmodelElement elem) {
+		addSubModelElement(elem);
 	}
 
 	/**
@@ -96,11 +127,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 +161,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 (getSubmodelElements()).values();
 	}
 
 	public void setOrdered(boolean value) {
@@ -164,38 +190,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,16 +222,39 @@
 	@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() {
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..ab1c677 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,5 +1,7 @@
 package org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement;
 
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Map;
 
 import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
@@ -15,7 +17,7 @@
  */
 public class Blob extends DataElement implements IBlob {
 	public static final String MIMETYPE="mimeType";
-	public static final String MODELTYPE = "blob";
+	public static final String MODELTYPE = "Blob";
 	
 	/**
 	 * Creates an empty Blob object
@@ -24,6 +26,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
@@ -62,17 +75,43 @@
 		// 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 void setValue(Object value) {
+		if(value instanceof byte[]) {
+			List<Byte> list = new ArrayList<>();
+			
+			byte[] bytes = (byte[]) value;
+			
+			for (int i = 0; i < bytes.length; i++) {
+				list.add(bytes[i]);
+			}
+			
+			put(Property.VALUE, list);
+		}
+		else {
+			throw new IllegalArgumentException("Given Object is not a byte[]");
+		}
+		
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
 	public byte[] getValue() {
-		return ((String) get(Property.VALUE)).getBytes();
+		if(!containsKey(Property.VALUE)) {
+			return null;
+		}
+		List<Number> list = (List<Number>) get(Property.VALUE);
+		byte[] ret = new byte[list.size()];
+		
+		for(int i = 0; i < list.size(); i++) {
+			ret[i] = list.get(i).byteValue();
+		}
+		
+		return ret;
 	}
 
 	public void setMimeType(String mimeType) {
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..6e3793b 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
@@ -7,6 +7,7 @@
 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,6 +16,17 @@
 		// 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));
+	}
 
 	/**
 	 * Returns true if the given submodel element map is recognized as a data element
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..5aeec79 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
@@ -26,6 +26,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
@@ -67,11 +76,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) {
+			put(Property.VALUE, (String) value);
+		}
+		else {
+			throw new IllegalArgumentException("Given Object is not a String");
+		}
+		
 	}
 
 	@Override
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..05f8031 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
@@ -28,6 +28,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);
@@ -53,8 +63,8 @@
 		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 +83,15 @@
 	protected KeyElements getKeyElement() {
 		return KeyElements.MULTILANGUAGEPROPERTY;
 	}
+	
+	@SuppressWarnings("unchecked")
+	@Override
+	public void setValue(Object value) {
+		if(LangStrings.isLangStrings(value)) {
+			put(VALUE, LangStrings.createAsFacade((Collection<Map<String, Object>>) value));
+		}
+		else {
+			throw new IllegalArgumentException("Given Object is not a LangStrings");
+		}
+	}
 }
\ No newline at end of file
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..a4298dc 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
@@ -62,15 +62,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,6 +75,17 @@
 		return Reference.createAsFacade((Map<String, Object>) get(Property.VALUE));
 	}
 	
+	@SuppressWarnings("unchecked")
+	@Override
+	public void setValue(Object value) {
+		if(Reference.isReference(value)) {
+			put(Property.VALUE, Reference.createAsFacade((Map<String, Object>) value));
+		}
+		else {
+			throw new IllegalArgumentException("Given Object is not a Reference");
+		}
+	}
+	
 	@Override
 	protected KeyElements getKeyElement() {
 		return KeyElements.REFERENCEELEMENT;
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..33c63c8 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
@@ -39,6 +39,24 @@
 		put(Property.VALUE, null);
 		put(Property.VALUEID, null);
 	}
+	
+	/**
+	 * Constructor accepting only mandatory attribute
+	 * @param idShort
+	 * @param valueType
+	 */
+	public Property(String idShort, PropertyValueTypeDef valueType) {
+		super(idShort);
+		setValueType(valueType);
+		setIdShort(idShort);
+		
+		// Add model type
+		putAll(new ModelType(MODELTYPE));
+
+		// Put attributes
+		put(Property.VALUE, null);
+		put(Property.VALUEID, null);
+	}
 
 	/**
 	 * Creates a Property object from a map
@@ -59,7 +77,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)));
 	}
 
 	/**
@@ -108,8 +126,11 @@
 
 	@Override
 	public void set(Object value) {
-		put(Property.VALUE, value);
-		put(Property.VALUETYPE, PropertyValueTypeDefHelper.getTypeWrapperFromObject(value));
+		put(Property.VALUE, PropertyValueTypeDefHelper.prepareForSerialization(value));
+		// Value type is only set if it is not set before
+		if(getValueType() == null) {
+			put(Property.VALUETYPE, PropertyValueTypeDefHelper.getTypeWrapperFromObject(value));
+		}
 	}
 
 	/**
@@ -124,13 +145,17 @@
 
 	@Override
 	public Object get() {
-		return get(Property.VALUE);
+		Object value = get(Property.VALUE);
+		if(value instanceof String) {
+			return PropertyValueTypeDefHelper.getJavaObject(value, getValueType());
+		}else {
+			return value;
+		}
 	}
 
 	@Override
-	public String getValueType() {
-		PropertyValueTypeDef def = PropertyValueTypeDefHelper.readTypeDef(get(Property.VALUETYPE));
-		return def!=null ? def.toString() : "";
+	public PropertyValueTypeDef getValueType() {
+		return PropertyValueTypeDefHelper.readTypeDef(get(Property.VALUETYPE));
 	}
 
 	/**
@@ -149,4 +174,14 @@
 	protected KeyElements getKeyElement() {
 		return KeyElements.PROPERTY;
 	}
+
+	@Override
+	public Object getValue() {
+		return get();
+	}
+	
+	@Override
+	public void setValue(Object value) {
+		set(value);
+	}
 }
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
index 61c4022..12204b0 100644
--- 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
@@ -12,7 +12,16 @@
  *
  */
 public enum PropertyValueTypeDef implements StandardizedLiteralEnum {
-	Double("double"), Float("float"), Integer("int"), String("string"), Boolean("boolean"), Void("void"), Null("null");
+	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;
 
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
index 4025801..936a2c0 100644
--- 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
@@ -1,8 +1,17 @@
 package org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetypedef;
 
+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.valuetypedef.PropertyValueTypeDef
@@ -62,13 +71,29 @@
 		PropertyValueTypeDef objectType;
 		
 		if (obj == null) {
-			objectType = PropertyValueTypeDef.Null;
+			objectType = PropertyValueTypeDef.None;
 		} else {
 			Class<?> c = obj.getClass();
-			if (c == int.class || c == Integer.class) {
+			if(c == byte.class || c == Byte.class) {
+				objectType = PropertyValueTypeDef.Int8;
+			}else if(c == short.class || c == Short.class) {
+				objectType = PropertyValueTypeDef.Int16;
+			}else if (c == int.class || c == Integer.class) {
 				objectType = PropertyValueTypeDef.Integer;
+			} else if (c == long.class || c == Long.class) {
+				objectType = PropertyValueTypeDef.Int64;
+			} else if (c == BigInteger.class) {
+				BigInteger tmp = (BigInteger) obj;
+				if (tmp.compareTo(new BigInteger("0")) > 0) {
+					objectType = PropertyValueTypeDef.PositiveInteger;
+				} else if (tmp.compareTo(new BigInteger("0")) < 0) {
+					objectType = PropertyValueTypeDef.NegativeInteger;
+				} else {
+					objectType = PropertyValueTypeDef.NonNegativeInteger;
+				}
+
 			} else if (c == void.class || c == Void.class) {
-				objectType = PropertyValueTypeDef.Void;
+				objectType = PropertyValueTypeDef.None;
 			} else if (c == boolean.class || c == Boolean.class) {
 				objectType = PropertyValueTypeDef.Boolean;
 			} else if (c == float.class || c == Float.class) {
@@ -78,6 +103,14 @@
 				objectType = PropertyValueTypeDef.Double;
 			} else if (c == String.class) {
 				objectType = PropertyValueTypeDef.String;
+			} else if (c == Duration.class) {
+				objectType = PropertyValueTypeDef.Duration;
+			} else if (c == Period.class) {
+				objectType = PropertyValueTypeDef.YearMonthDuration;
+			} else if (c == QName.class) {
+				objectType = PropertyValueTypeDef.QName;
+			} else if (c == XMLGregorianCalendar.class) {
+				objectType = PropertyValueTypeDef.DateTime;
 			} else {
 				throw new RuntimeException("Cannot map object " + obj + " to any PropertyValueTypeDef");
 			}
@@ -86,6 +119,116 @@
 	}
 
 	/**
+	 * Map the PropertyValueType to Java type
+	 * 
+	 */
+	public static Object getJavaObject(Object value, PropertyValueTypeDef 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;
+
+	}
+
+	/**
 	 * Creates the appropriate type map for a given type
 	 * 
 	 * @param type
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..ec21f31
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/range/Range.java
@@ -0,0 +1,133 @@
+package org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.range;
+
+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;
+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;
+
+/**
+ * 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(PropertyValueTypeDef valueType) {
+		this();
+		setValueType(valueType);
+	}
+
+	/**
+	 * Constructor accepting only mandatory attribute
+	 * @param idShort
+	 * @param valueType
+	 */
+	public Range(String idShort, PropertyValueTypeDef valueType) {
+		super(idShort);
+		// Add model type
+		putAll(new ModelType(MODELTYPE));
+		put(VALUETYPE, valueType);
+	}
+	
+	public Range(PropertyValueTypeDef 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)
+				|| (modelType == null && (map.containsKey(MIN) && map.containsKey(MAX) && map.containsKey(VALUETYPE)));
+	}
+
+	private void setValueType(PropertyValueTypeDef valueType) {
+		put(Range.VALUETYPE, PropertyValueTypeDefHelper.getWrapper(valueType));
+	}
+
+	@Override
+	public PropertyValueTypeDef getValueType() {
+		return PropertyValueTypeDefHelper.readTypeDef(get(Range.VALUETYPE));
+	}
+
+	@Override
+	public Object getMin() {
+		Object value = get(MIN);
+		if(value instanceof String) {
+			return PropertyValueTypeDefHelper.getJavaObject(value, getValueType());
+		}else {
+			return value;
+		}
+	}
+
+	@Override
+	public Object getMax() {
+		Object value = get(MAX);
+		if(value instanceof String) {
+			return PropertyValueTypeDefHelper.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);
+			Object minValue = rv.getMin();
+			Object maxValue = rv.getMax();
+			
+			put(Range.MIN, PropertyValueTypeDefHelper.prepareForSerialization(minValue));
+			put(Range.MAX, PropertyValueTypeDefHelper.prepareForSerialization(maxValue));
+			if(getValueType() == null) { 
+				setValueType(PropertyValueTypeDefHelper.getType(minValue));
+			}
+		} else {
+			throw new IllegalArgumentException("Given Object is not a RangeValue");
+		}
+	}
+
+}
\ No newline at end of file
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..a6b537c
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/range/RangeValue.java
@@ -0,0 +1,56 @@
+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) {
+		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..ce89290 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
@@ -32,6 +32,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 +64,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
 	 * 
@@ -91,4 +110,21 @@
 		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");
+		}
+	}
 }
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..bf60341
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/entity/EntityValue.java
@@ -0,0 +1,80 @@
+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) {
+		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..a67eab7 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
@@ -30,6 +30,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;
@@ -53,7 +66,7 @@
 	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 +74,20 @@
 	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");
+		}
+	}
 }
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..ded8eca
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/operation/AsyncInvocation.java
@@ -0,0 +1,69 @@
+package org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation;
+
+import java.util.concurrent.CompletableFuture;
+import java.util.function.Function;
+
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IAsyncInvocation;
+import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
+
+/**
+ * Local implementation of IAsyncInvocation
+ * 
+ * @author conradi
+ *
+ */
+public class AsyncInvocation implements IAsyncInvocation {
+	
+	private static final String DEFAULT_REQUEST_ID = "0";
+
+	private String operationId;
+	private String requestId;
+	
+	private CompletableFuture<Object> future;
+	
+	
+	@SuppressWarnings("unchecked")
+	public AsyncInvocation(Operation operation, String requestId, Object... parameters) {
+		operationId = operation.getIdShort();
+		this.requestId = requestId;
+		
+		Function<Object[], Object> invokable = (Function<Object[], Object>) operation.get(Operation.INVOKABLE);
+		future = CompletableFuture.supplyAsync(() -> invokable.apply(parameters));
+	}
+	
+	public AsyncInvocation(Operation operation, Object... parameters) {
+		this(operation, DEFAULT_REQUEST_ID, parameters);
+	}
+	
+	public AsyncInvocation(IModelProvider provider, String operationId, String requestId, Object... parameters) {
+		this.operationId = operationId;
+		this.requestId = requestId;
+		
+		future = CompletableFuture.supplyAsync(() -> provider.invokeOperation("", parameters));
+	}
+	
+	@Override
+	public Object getResult() {
+		try {
+			return future.get();
+		} catch (Exception e) {
+			// Some RuntimeException occured in the executed function			
+			throw new OperationExecutionErrorException("Exception while executing Invocation '"
+					+ requestId + "' of Operation '" + operationId + "'", e.getCause());
+		}
+	}
+	
+	@Override
+	public boolean isFinished() {
+		return future.isDone();
+	}
+
+	public String getRequestId() {
+		return requestId;
+	}
+
+	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..7d80755 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
@@ -29,6 +29,8 @@
 
 	public static final String INVOKABLE = "invokable";
 	public static final String MODELTYPE = "Operation";
+	
+	public static final String INVOKE = "invoke";
 
 	/**
 	 * Constructor
@@ -49,6 +51,28 @@
 		// Extension of DAAS specification for function storage
 		put(INVOKABLE, null);
 	}
+	
+	/**
+	 * Constructor accepting only mandatory attribute
+	 * @param idShort
+	 */
+	public Operation(String idShort) {
+		super(idShort);
+		// Add model type
+		putAll(new ModelType(MODELTYPE));
+
+		// Input variables
+		setInputVariables(new ArrayList<OperationVariable>());
+
+		// Output variables
+		setOutputVariables(new ArrayList<OperationVariable>());
+
+		// Variables, that are input and output
+		setInOutputVariables(new ArrayList<OperationVariable>());
+
+		// Extension of DAAS specification for function storage
+		setInvocable(null);
+	}
 
 	/**
 	 * 
@@ -108,10 +132,18 @@
 	/**
 	 * 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
@@ -149,6 +181,12 @@
 		return ((Function<Object[], Object>) get(INVOKABLE)).apply(params);
 	}
 
+	@Override
+	public AsyncInvocation invokeAsync(Object... params) {
+		AsyncInvocation invocation = new AsyncInvocation(this, params);
+		return invocation;
+	}
+
 	public void setInputVariables(Collection<OperationVariable> in) {
 		put(Operation.IN, in);
 	}
@@ -194,4 +232,14 @@
 	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");
+	}
 }
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..24242a4
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/operation/OperationExecutionErrorException.java
@@ -0,0 +1,51 @@
+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/relationship/RelationshipElement.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/relationship/RelationshipElement.java
index bb9d5c6..39d7a15 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
@@ -41,7 +41,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,6 +50,17 @@
 	}
 	
 	/**
+	 * 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
@@ -67,7 +78,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) {
@@ -96,4 +107,22 @@
 	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);
+			setFirst(rev.getFirst());
+			setSecond(rev.getSecond());
+		} else {
+			throw new IllegalArgumentException("Given Object is not an RelationshipElementValue");
+		}
+	}
 }
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..f29ecfc
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/relationship/RelationshipElementValue.java
@@ -0,0 +1,61 @@
+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> {
+
+	private 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) {
+		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/MultiSubmodelElementProvider.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/MultiSubmodelElementProvider.java
new file mode 100644
index 0000000..9b3c0b9
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/MultiSubmodelElementProvider.java
@@ -0,0 +1,166 @@
+package org.eclipse.basyx.submodel.restapi;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+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.
+ *
+ * @author espen, conradi
+ *
+ */
+public class MultiSubmodelElementProvider extends MetaModelProvider {
+	// 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.getModelPropertyValue("");
+		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).getModelPropertyValue(subPath);
+		} else {
+			throw new MalformedRequestException("Given path '" + path + "' does not start with /submodelElements");
+		}
+	}
+
+	@Override
+	public Object getModelPropertyValue(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 setModelPropertyValue(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).setModelPropertyValue(subPath, newValue);
+	}
+
+	@Override
+	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");
+		}
+		
+		if (pathElements.length == 2) {
+			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..ad6afe0 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
@@ -3,8 +3,10 @@
 import java.util.Map;
 
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation;
+import org.eclipse.basyx.submodel.restapi.operation.AsyncOperationHandler;
 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;
 
@@ -17,6 +19,10 @@
 public class OperationProvider extends MetaModelProvider {
 
 	IModelProvider modelProvider;
+	
+	public static final String ASYNC = "?async=true";
+	public static final String INVOCATION_LIST = "invocationList";
+
 
 	public OperationProvider(IModelProvider modelProvider) {
 		this.modelProvider = modelProvider;
@@ -24,49 +30,78 @@
 
 	@Override
 	public Object getModelPropertyValue(String path) throws ProviderException {
+		String[] splitted = VABPathTools.splitPath(path);
 		if (path.isEmpty()) {
 			return modelProvider.getModelPropertyValue("");
+		} else if (splitted[0].equals(INVOCATION_LIST) && splitted.length == 2) {
+			String requestId = splitted[1];
+			String operationId = getIdShort(modelProvider.getModelPropertyValue(""));
+			return AsyncOperationHandler.retrieveResult(operationId, requestId);
+			
 		} 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");
+		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 {
+		
+		boolean async = path.endsWith(ASYNC);
+
+		// remove the "invoke" from the end of the path
+		path = VABPathTools.stripInvokeFromPath(path);
+		
 		// Unwrap parameters, if they are wrapped
 		for (int i = 0; i < parameters.length; i++) {
 			parameters[i] = unwrapParameter(parameters[i]);
 		}
 
+		String operationId = "";
 		// Invoke /invokable instead of an Operation property if existent
 		Object childElement = modelProvider.getModelPropertyValue(path);
-		if (childElement instanceof Map<?, ?> && ((Map<?, ?>) childElement).containsKey(Operation.INVOKABLE)) {
+		if (Operation.isOperation(childElement)) {
 			path = VABPathTools.concatenatePaths(path, Operation.INVOKABLE);
+			operationId = getIdShort(childElement);
 		}
-
-		// Forward call to model provider
-		return modelProvider.invokeOperation(path, parameters);
+		
+		if(async) {
+			return AsyncOperationHandler.invokeAsync(new VABElementProxy(path, modelProvider), operationId, parameters);
+		} else {
+			// Forward call to model provider
+			return modelProvider.invokeOperation(path, parameters);			
+		}
+	}
+	
+	@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");
+		}
 	}
 
 }
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..875105e 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,6 +1,5 @@
 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;
@@ -31,20 +30,10 @@
 
 		// Handle "/value" path
 		if (path.equals(Property.VALUE)) {
-			// Build map containing value & valueType
+			// return value
 			Map<String, Object> p = (Map<String, Object>) proxy.getModelPropertyValue("");
-			Map<String, Object> ret = new HashMap<>();
-			Object o = p.get(Property.VALUE);
+			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("");
@@ -62,28 +51,28 @@
 			proxy.setModelPropertyValue(Property.VALUE, newValue);
 			proxy.setModelPropertyValue(Property.VALUETYPE, PropertyValueTypeDefHelper.getTypeWrapperFromObject(newValue));
 		} 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
index 97ebf4f..2669bcd 100644
--- 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
@@ -5,6 +5,8 @@
 import java.util.List;
 import java.util.Map;
 
+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;
@@ -34,6 +36,9 @@
  */
 public class SubModelProvider extends MetaModelProvider {
 
+	public static final String VALUES = "values";
+	public static final String SUBMODEL = "submodel";
+	
 	ISubmodelAPI submodelAPI;
 
 	/**
@@ -75,9 +80,10 @@
 	 */
 	private String removeSubmodelPrefix(String path) {
 		path = VABPathTools.stripSlashes(path);
-		if (path.startsWith("submodel/")) {
+		String submodelWithSlash = SUBMODEL + "/";
+		if (path.startsWith(submodelWithSlash)) {
 			path = path.replaceFirst("submodel/", "");
-		} else if (path.equals("submodel")) {
+		} else if (path.equals(SUBMODEL)) {
 			path = "";
 		}
 		path = VABPathTools.stripSlashes(path);
@@ -89,31 +95,41 @@
 		VABPathTools.checkPathForNull(path);
 		path = removeSubmodelPrefix(path);
 		if (path.isEmpty()) {
-			return submodelAPI.getSubmodel();
+			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);
-			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();
-				}
+			// 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
 				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);
+					return submodelAPI.getSubmodelElementValue(idShort);
+				} 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, splitted[splitted.length - 1]);
 				} 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);
+						return submodelAPI.getNestedSubmodelElementValue(idShorts);
 					} else {
 						return submodelAPI.getNestedSubmodelElement(idShorts);
 					}
@@ -127,7 +143,7 @@
 		// Create list from array and wrap it in ArrayList to ensure modifiability
 		List<String> idShorts = new ArrayList<>(Arrays.asList(splitted));
 
-		// Drop inital "submodels"
+		// Drop inital "submodelElements"
 		idShorts.remove(0);
 
 		// If value is contained in path, remove it
@@ -138,7 +154,7 @@
 	}
 
 	private boolean isPropertyValuePath(String[] splitted) {
-		return splitted.length == 3 && splitted[0].equals(SubmodelElementProvider.PROPERTIES) && endsWithValue(splitted);
+		return splitted.length == 3 && splitted[0].equals(MultiSubmodelElementProvider.ELEMENTS) && endsWithValue(splitted);
 	}
 
 	private boolean endsWithValue(String[] splitted) {
@@ -146,9 +162,14 @@
 	}
 
 	private boolean isSubmodelElementListPath(String[] splitted) {
-		return splitted.length > 2 && splitted[0].equals(SubmodelElementProvider.ELEMENTS);
+		return splitted.length > 2 && splitted[0].equals(MultiSubmodelElementProvider.ELEMENTS);
 	}
 
+	private boolean isInvocationListPath(String[] splitted) {
+		return splitted.length > 2 && splitted[splitted.length - 2].equals(OperationProvider.INVOCATION_LIST);
+	}
+
+	@SuppressWarnings("unchecked")
 	@Override
 	public void setModelPropertyValue(String path, Object newValue) throws ProviderException {
 		path = removeSubmodelPrefix(path);
@@ -156,25 +177,25 @@
 			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);
+			if (endsWithValue(splitted)) {
+				submodelAPI.updateNestedSubmodelElement(getIdShorts(splitted), newValue);
 			} else {
-				throw new MalformedRequestException("Update on path " + path + " not supported");
+				
+				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(getIdShorts(splitted), element);
 			}
 		}
 	}
 
-	@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));
-		}
+		throw new MalformedRequestException("POST (create) on '" + path + "' not allowed. Use PUT (set) instead.");
 	}
 
 	@Override
@@ -182,9 +203,12 @@
 		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);
+			if (isQualifier(splitted[0])) {
+				if (splitted.length > 2) {
+					submodelAPI.deleteNestedSubmodelElement(getIdShorts(splitted));
+				} else {
+					submodelAPI.deleteSubmodelElement(splitted[1]);
+				}
 			} else {
 				throw new MalformedRequestException("Path " + path + " not supported for delete");
 			}
@@ -194,7 +218,7 @@
 	}
 
 	private boolean isQualifier(String str) {
-		return str.equals(SubmodelElementProvider.ELEMENTS) || str.equals(SubmodelElementProvider.OPERATIONS) || str.equals(SubmodelElementProvider.PROPERTIES);
+		return str.equals(MultiSubmodelElementProvider.ELEMENTS);
 	}
 
 	@Override
@@ -206,14 +230,19 @@
 	public Object invokeOperation(String path, Object... parameters) throws ProviderException {
 		path = removeSubmodelPrefix(path);
 		if (path.isEmpty()) {
-			throw new MalformedRequestException("Invalid access");
+			throw new MalformedRequestException("Given path must not be empty");
 		} else {
 			String[] splitted = VABPathTools.splitPath(path);
-			if (splitted.length == 2 && splitted[0].equals(SubmodelElementProvider.OPERATIONS)) {
-				String idShort = splitted[1];
-				return submodelAPI.invokeOperation(idShort, parameters);
+			if (VABPathTools.isOperationInvokationPath(path)) {
+				if(path.endsWith(OperationProvider.ASYNC)) {
+					List<String> idShorts = getIdShorts(splitted);
+					idShorts.remove(idShorts.size() - 1);
+					return submodelAPI.invokeNestedOperationAsync(idShorts, parameters);
+				} else {
+					return submodelAPI.invokeNestedOperation(getIdShorts(splitted), parameters);
+				}
 			} else {
-				throw new MalformedRequestException("Unknown path " + path);
+				throw new MalformedRequestException("Given path '" + path + "' does not end in /invoke");
 			}
 		}
 	}
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..014fab3 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,22 +1,19 @@
 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 {
 
@@ -27,55 +24,57 @@
 	}
 
 	/**
-	 * 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 {
 		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.getModelPropertyValue(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.getModelPropertyValue(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);
 		}
 	}
 
+	@SuppressWarnings("unchecked")
 	@Override
 	public void setModelPropertyValue(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.setModelPropertyValue(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.setModelPropertyValue(path, value);
 		} else {
 			// Directly access an element inside of the collection
 			String idShort = pathElements[0];
@@ -89,8 +88,9 @@
 		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);
+			proxy.createValue(valuePath, newEntity);
 		} else {
 			// Directly access an element inside of the collection
 			String idShort = pathElements[0];
@@ -101,22 +101,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 +130,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..7a9bfe9 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,145 @@
 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";
 
-	// 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();
+	@SuppressWarnings("unchecked")
+	public static IModelProvider getElementProvider(IModelProvider proxy) {
+		Map<String, Object> elementMap = (Map<String, Object>) proxy.getModelPropertyValue("");
+		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 {
-			// No other qualifier in a submodel element container can be directly accessed
-			throw getUnknownPathException(path);
+			return proxy;
 		}
 	}
 
-	/**
-	 * 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);
+		path = VABPathTools.stripSlashes(path);
+
+		if (path.equals(MultiSubmodelElementProvider.VALUE)) {
+			// Handle "/value" path
+			// return value
+			
+			if(specializedProvider) {
+				return proxy.getModelPropertyValue(path);
+			}
+			
+			Map<String, Object> elementMap = (Map<String, Object>) proxy.getModelPropertyValue("");
+			
+			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 {
-			return handleDetailGet(path);
+			// Path has more Elements -> pass it to Provider below
+			return proxy.getModelPropertyValue(path);
 		}
 	}
 
 	@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");
+		path = VABPathTools.stripSlashes(path);
+		
+		if(!path.endsWith(MultiSubmodelElementProvider.VALUE)) {
+			throw new MalformedRequestException("The given path '" + path + "' does not end in /value.");
 		}
-
-		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 (!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.getModelPropertyValue("");
+			
+			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.setModelPropertyValue("", element);
+			
 		} 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
+			proxy.setModelPropertyValue(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/api/ISubmodelAPI.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/api/ISubmodelAPI.java
index 214e7b7..116dca1 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
@@ -5,7 +5,6 @@
 
 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;
 
 /**
@@ -24,38 +23,49 @@
 	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 idShorts
+	 *            the idShort path to the submodelElement
+	 * @param  elem
+	 *            the submodelElement to be added
+	 */
+	public void addSubmodelElement(List<String> idShorts, ISubmodelElement elem);
+
+	/**
+	 * Retrieves a submodelElement
 	 * 
 	 * @param idShort
-	 *            of the submodel element
-	 * @return the submodel element
+	 *            of the submodelElement
+	 * @return the submodelElement
 	 */
 	public ISubmodelElement getSubmodelElement(String idShort);
 
 	/**
-	 * Removes a submodel element from the submodel
+	 * Removes a submodelElement from the submodel
 	 * 
 	 * @param idShort
-	 *            of the element to be removed
+	 *            of the submodelElement to be removed
 	 */
 	public void deleteSubmodelElement(String idShort);
 
 	/**
+	 * Removes a submodelElement from a SubmodelElementCollection
+	 * 
+	 * @param idShort
+	 *            of the submodelElement to be removed
+	 */
+	public void deleteNestedSubmodelElement(List<String> idShorts);
+
+	/**
 	 * Helper function for quick access of operations
 	 * 
 	 * @return all operations contained by the submodel
@@ -63,44 +73,54 @@
 	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
+	 *            of 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 idShort, Object newValue);
 
 	/**
-	 * Retrieves the value of a property
-	 * 
-	 * @param idShort
-	 *            of the property
-	 * @return property value
-	 */
-	public Object getPropertyValue(String idShort);
-
-	/**
-	 * Retrieves the value of a property nested inside a SubmodelElementCollection.
+	 * Updates the value of a submodelElement nested inside a SubmodelElementCollection.
 	 * 
 	 * @param idShorts
-	 *            the idShort path to the property
+	 *            the idShort path to the submodelElement
+	 * @param newValue
+	 *            new value of the submodelElement
 	 */
-	public Object getNestedPropertyValue(List<String> idShorts);
+	public void updateNestedSubmodelElement(List<String> idShorts, Object newValue);
+
+	/**
+	 * Retrieves the value of a submodelElement
+	 * 
+	 * @param idShort
+	 *            of the submodelElement
+	 * @return submodelElement value
+	 */
+	public Object getSubmodelElementValue(String idShort);
+
+	/**
+	 * Retrieves the value of a submodelElement nested inside a SubmodelElementCollection.
+	 * 
+	 * @param idShorts
+	 *            the idShort path to the submodelElement
+	 */
+	public Object getNestedSubmodelElementValue(List<String> idShorts);
 
 	/**
 	 * Retrieves a submodel element nested inside a SubmodelElementCollection
 	 * 
 	 * @param idShorts
-	 *            the idShort path to the property
+	 *            the idShort path to the submodelElement
 	 * @return
 	 */
 	public ISubmodelElement getNestedSubmodelElement(List<String> idShorts);
@@ -115,4 +135,38 @@
 	 * @return the result of the operation
 	 */
 	public Object invokeOperation(String idShort, Object... params);
+
+	/**
+	 * Invokes an operation
+	 * 
+	 * @param idShorts
+	 *            the idShort path to the operation
+	 * @param params
+	 *            to be passed to the operation
+	 * @return the result of the operation
+	 */
+	public Object invokeNestedOperation(List<String> idShorts, Object... params);
+
+	/**
+	 * Invokes an operation asynchronously
+	 * 
+	 * @param idShorts
+	 *            the idShort path to the operation
+	 * @param params
+	 *            to be passed to the operation
+	 * @return the requestId of the invocation
+	 */
+	public Object invokeNestedOperationAsync(List<String> idShorts, Object... params);
+	
+	/**
+	 * Gets the result of an asynchronously invoked operation
+	 * 
+	 * @param idShorts 
+	 *            the idShort path to 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(List<String> idShorts, String requestId);
+
 }
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..b7a1b39
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/operation/AsyncOperationHandler.java
@@ -0,0 +1,94 @@
+package org.eclipse.basyx.submodel.restapi.operation;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.AsyncInvocation;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.OperationExecutionErrorException;
+import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
+import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
+
+/**
+ * Helperclass used to keep the asynchronously operations
+ * This class is used in a static way. As each request is handled by new Providers
+ * 
+ * @author conradi
+ *
+ */
+public class AsyncOperationHandler {
+
+	private static int count = 0;
+	
+	private static Map<String, AsyncInvocation> map = new HashMap<>();
+	
+	/**
+	 * Invokes an Operation and returns its requestId
+	 * 
+	 * @param operation the Operation to be invoked
+	 * @param parameters to be given to the operation
+	 * @return the requestId
+	 */
+	public static String invokeAsync(IModelProvider provider, String operationId, Object... parameters) {
+		String requestId = getRequestId();
+		AsyncInvocation invocation = new AsyncInvocation(provider, operationId, requestId, parameters);
+		synchronized (map) {
+			map.put(requestId, invocation);
+		}
+		return requestId;
+	}
+	
+	/**
+	 * 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 operationIdShort, String requestId) {
+		if(!map.containsKey(requestId)) {
+			throw new ResourceNotFoundException("RequestId '" + requestId + "' not found.");
+		}
+		
+		AsyncInvocation invocation = map.get(requestId);
+		
+		if(!(invocation.getOperationId().equals(operationIdShort) || invocation.getOperationId().isEmpty())) {
+			throw new ResourceNotFoundException(
+					"RequestId '" + requestId + "' does not belong to Operation '" + operationIdShort + "'");
+		}
+		
+		if(!invocation.isFinished()) {
+			return OperationResult.EXECUTION_NOT_YET_FINISHED.toString();
+		}
+		
+		// Remove the Invocation if it is finished and its result was retrieved
+		synchronized (map) {
+			map.remove(requestId);
+		}
+		
+		
+		try {
+			return invocation.getResult();
+		} catch (OperationExecutionErrorException e) {
+			return OperationResult.EXECUTION_ERROR.toString();
+		}
+	}
+	
+	/**
+	 * Checks if a given requestId exists
+	 * 
+	 * @param requestId the id to be checked
+	 * @return if the id exists
+	 */
+	public static synchronized boolean hasRequestId(String requestId) {
+		return map.containsKey(requestId);
+	}
+	
+	/**
+	 * Generates a unique requestId
+	 * 
+	 * @return a unique requestId
+	 */
+	private static synchronized String getRequestId() {
+		return Integer.toString(count++);
+	}	
+}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/operation/OperationResult.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/operation/OperationResult.java
new file mode 100644
index 0000000..0c4b5f7
--- /dev/null
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/submodel/restapi/operation/OperationResult.java
@@ -0,0 +1,6 @@
+package org.eclipse.basyx.submodel.restapi.operation;
+
+public enum OperationResult {
+	EXECUTION_ERROR, EXECUTION_NOT_YET_FINISHED;
+
+}
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..a094e8d 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,20 +1,20 @@
 package org.eclipse.basyx.submodel.restapi.vab;
 
 import java.util.Collection;
-import java.util.HashSet;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.stream.Collectors;
 
 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.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;
@@ -50,9 +50,9 @@
 	 * @return returns the SubmodelElementProvider pointing to the contained
 	 *         submodelelements
 	 */
-	private SubmodelElementProvider getElementProvider() {
+	private MultiSubmodelElementProvider getElementProvider() {
 		IModelProvider elementProxy = new VABElementProxy(SubModel.SUBMODELELEMENT, modelProvider);
-		return new SubmodelElementProvider(elementProxy);
+		return new MultiSubmodelElementProvider(elementProxy);
 	}
 
 	@SuppressWarnings("unchecked")
@@ -61,83 +61,87 @@
 		// For access on the container property root, return the whole model
 		Map<String, Object> map = (Map<String, Object>) modelProvider.getModelPropertyValue("");
 
-		// 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);
+	}
+
+	@Override
+	public void addSubmodelElement(List<String> idShorts, ISubmodelElement elem) {
+		getElementProvider().createValue(buildNestedElementPath(idShorts), elem);
 	}
 
 	@Override
 	public void deleteSubmodelElement(String idShort) {
-		getElementProvider().deleteValue(SubmodelElementProvider.ELEMENTS + "/" + idShort);
+		getElementProvider().deleteValue(MultiSubmodelElementProvider.ELEMENTS + "/" + idShort);
+	}
+
+	@Override
+	public void deleteNestedSubmodelElement(List<String> idShorts) {
+		getElementProvider().deleteValue(buildNestedElementPath(idShorts));
+	}
+
+	@Override
+	public Collection<IOperation> getOperations() {
+		return getSubmodelElements().stream().filter(e -> e instanceof IOperation).map(e -> (IOperation) e).collect(Collectors.toList());
 	}
 
 	@SuppressWarnings("unchecked")
 	@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()));
-		}
-	}
-
-	@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()
+				.getModelPropertyValue(MultiSubmodelElementProvider.ELEMENTS);
+		return elements.stream().map(SubmodelElement::createAsFacade).collect(Collectors.toList());
 	}
 
 	@Override
-	public void updateProperty(String idShort, Object newValue) {
+	public void updateSubmodelElement(String idShort, Object newValue) {
 		getElementProvider().setModelPropertyValue(buildValuePathForProperty(idShort), newValue);
 	}
 
 	@Override
-	public Object getPropertyValue(String idShort) {
+	public void updateNestedSubmodelElement(List<String> idShorts, Object newValue) {
+		getElementProvider().setModelPropertyValue(buildNestedElementPath(idShorts) + "/" + Property.VALUE, newValue);
+	}
+
+	@Override
+	public Object getSubmodelElementValue(String idShort) {
 		return getElementProvider().getModelPropertyValue(buildValuePathForProperty(idShort));
 	}
 
 	@SuppressWarnings("unchecked")
 	@Override
 	public ISubmodelElement getSubmodelElement(String idShort) {
-		return SubmodelElement.createAsFacade((Map<String, Object>) getElementProvider().getModelPropertyValue(SubmodelElementProvider.ELEMENTS + "/" + idShort));
+		return SubmodelElement.createAsFacade((Map<String, Object>) getElementProvider().getModelPropertyValue(MultiSubmodelElementProvider.ELEMENTS + "/" + idShort));
 	}
 
 	@Override
 	public Object invokeOperation(String idShort, Object... params) {
-		return getElementProvider().invokeOperation(SubmodelElementProvider.OPERATIONS + "/" + idShort, params);
+		return getElementProvider().invokeOperation(MultiSubmodelElementProvider.ELEMENTS + "/" + idShort, params);
+	}
+	
+	@Override
+	public Object invokeNestedOperation(List<String> idShorts, Object... params) {
+		return getElementProvider().invokeOperation(buildNestedElementPath(idShorts), params);
+	}
+	
+	@Override
+	public Object invokeNestedOperationAsync(List<String> idShorts, Object... params) {
+		return getElementProvider().invokeOperation(buildNestedElementPath(idShorts) + "/" + Operation.INVOKE + OperationProvider.ASYNC, params);
 	}
 
 	private String buildValuePathForProperty(String idShort) {
-		return SubmodelElementProvider.PROPERTIES + "/" + idShort + "/" + Property.VALUE;
+		return MultiSubmodelElementProvider.ELEMENTS + "/" + idShort + "/" + Property.VALUE;
 	}
 
 	@Override
-	public Object getNestedPropertyValue(List<String> idShorts) {
+	public Object getNestedSubmodelElementValue(List<String> idShorts) {
 		return getElementProvider().getModelPropertyValue(buildNestedElementPath(idShorts) + "/" + Property.VALUE);
 	}
 
@@ -147,12 +151,18 @@
 		Map<String, Object> map = (Map<String, Object>) getElementProvider().getModelPropertyValue(buildNestedElementPath(idShorts));
 		return SubmodelElement.createAsFacade(map);
 	}
+	
+	@Override
+	public Object getOperationResult(List<String> idShorts, String requestId) {
+		return getElementProvider().getModelPropertyValue(buildNestedElementPath(idShorts) + "/" + OperationProvider.INVOCATION_LIST + "/" + requestId);
+	}
 
 	/**
 	 * @param idShorts
 	 * @return
 	 */
 	private String buildNestedElementPath(List<String> idShorts) {
-		return SubmodelElementProvider.ELEMENTS + "/" + VABPathTools.concatenatePaths(idShorts.toArray(new String[1]));
+		return MultiSubmodelElementProvider.ELEMENTS + "/" + VABPathTools.concatenatePaths(idShorts.toArray(new String[0]));
 	}
+
 }
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..31119fc 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
@@ -2,6 +2,7 @@
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.UUID;
 
 import org.eclipse.basyx.vab.coder.json.metaprotocol.IMetaProtocolHandler;
 import org.eclipse.basyx.vab.coder.json.metaprotocol.MetaprotocolHandler;
@@ -12,6 +13,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 +27,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
@@ -83,7 +89,17 @@
 		String message = provider.getModelPropertyValue(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
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..6a3dd15 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,8 @@
 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 +114,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 +146,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,7 +166,7 @@
 	 * 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
@@ -171,7 +176,7 @@
 			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 +191,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 {
@@ -198,7 +203,7 @@
 			providerBackend.setModelPropertyValue(path, parameter);
 
 			// Send response
-			outputStream.write("");
+			outputStream.write("".getBytes(StandardCharsets.UTF_8));
 
 		} catch (Exception e) {
 			sendException(outputStream, e);
@@ -211,7 +216,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 +249,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 +265,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 +280,7 @@
 			}
 
 			// Send response
-			outputStream.write("");
+			outputStream.write("".getBytes(StandardCharsets.UTF_8));
 
 		} catch (Exception e) {
 			sendException(outputStream, e);
@@ -291,7 +296,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 +306,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/GSONTools.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/coder/json/serialization/GSONTools.java
index 34f1eec..beb438f 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
@@ -7,6 +7,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;
@@ -98,7 +99,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 +150,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 +171,7 @@
 		}
 	}
 
+
 	/**
 	 * Serializes either string, number or boolean to a JsonPrimitive
 	 * 
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..408604d 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
@@ -35,6 +35,12 @@
 	}
 
 
+	public ProviderException(String message, Throwable cause) {
+		super(cause);
+		this.message = message;
+	}
+
+
 	/**
 	 * Return detailed message
 	 */
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..1454e07 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
@@ -23,7 +23,7 @@
 */
 
 public class VABModelMap<V extends Object> implements Map<String, V> {
-	Map<String, V> map;
+	protected Map<String, V> map;
 
 	/**
 	 * Default constructor
@@ -183,6 +183,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) {
@@ -199,14 +205,49 @@
 		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 testEquivalence(thisMap, otherMap);
+		}
+	}
+ 
+	@SuppressWarnings("unchecked")
+	private boolean testEquivalence(Map<String, Object> a, Map<String, Object> b) {
+		if (a.size() != b.size()) {
+			return false;
+		}
+
+		for (String k : a.keySet()) {
+			Object aVal = a.get(k);
+			Object bVal = b.get(k);
+			if (aVal instanceof Map<?, ?> && !(bVal instanceof Map<?, ?>)) {
 				return false;
+			} else if (aVal instanceof Map<?, ?> && bVal instanceof Map<?, ?>) {
+				return testEquivalence((Map<String, Object>) aVal, (Map<String, Object>) bVal);
+			} else {
+				if (aVal == null) {
+					return bVal == null;
+				} else {
+					if (aVal.equals(bVal)) {
+						return true;
+					} else {
+						if (aVal instanceof Collection<?> && bVal instanceof Collection<?>) {
+							Collection<?> aCol = (Collection<?>) aVal;
+							Collection<?> bCol = (Collection<?>) bVal;
+							return aCol.size() == bCol.size() && aCol.containsAll(bCol);
+						} else {
+							return false;
+						}
+					}
+				}
 			}
 		}
 		return true;
 	}
+
+	@Override
+	public String toString() {
+		return map.toString();
+	}
 }
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..89642a4 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
@@ -6,6 +6,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 +230,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 +241,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 +364,22 @@
 			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;
+	}
 }
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..6a35c57 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
@@ -99,6 +99,9 @@
 	@SuppressWarnings("unchecked")
 	@Override
 	public Object invokeOperation(String path, Object... parameters) {
+		
+		path = VABPathTools.stripInvokeFromPath(path);
+		
 		Object childElement = getModelPropertyValue(path);
 
 		// Invoke operation for function interfaces
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..fe7c99f 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
@@ -67,4 +67,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/basyx/connector/BaSyxConnector.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/basyx/connector/BaSyxConnector.java
index bb0f851..d9fc5f0 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
@@ -278,4 +278,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/server/VABBaSyxTCPInterface.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/basyx/server/VABBaSyxTCPInterface.java
index a33e8da..74819af 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
@@ -2,7 +2,6 @@
 
 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 +80,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 +105,7 @@
 
 			// Send response frame
 			output.flush();
-			sendResponseFrame(byteArrayOutput);
+			sendResponseFrame(output);
 
 			break;
 		}
@@ -133,7 +131,7 @@
 
 			// Send response frame
 			output.flush();
-			sendResponseFrame(byteArrayOutput);
+			sendResponseFrame(output);
 
 			break;
 		}
@@ -159,7 +157,7 @@
 
 			// Send response frame
 			output.flush();
-			sendResponseFrame(byteArrayOutput);
+			sendResponseFrame(output);
 
 			break;
 		}
@@ -194,7 +192,7 @@
 
 			// Send response frame
 			output.flush();
-			sendResponseFrame(byteArrayOutput);
+			sendResponseFrame(output);
 
 			break;
 		}
@@ -219,7 +217,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..7c14785 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,5 +1,6 @@
 package org.eclipse.basyx.vab.protocol.http.connector;
 
+import javax.ws.rs.ProcessingException;
 import javax.ws.rs.client.Client;
 import javax.ws.rs.client.ClientBuilder;
 import javax.ws.rs.client.Entity;
@@ -15,6 +16,8 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import io.netty.handler.codec.http.HttpMethod;
+
 /**
  * HTTP connector class
  * 
@@ -44,7 +47,7 @@
 	}
 
 	public HTTPConnector(String address) {
-		this(address, MediaType.APPLICATION_JSON);
+		this(address, MediaType.APPLICATION_JSON + ";charset=UTF-8");
 	}
 
 	public HTTPConnector(String address, String mediaType) {
@@ -125,7 +128,6 @@
 		// Build request, set JSON encoding
 		Builder request = resource.request();
 		request.accept(mediaType);
-
 		// Return JSON request
 		return request;
 	}
@@ -159,7 +161,12 @@
 		Builder request = retrieveBuilder(servicePath);
 
 		// Perform request
-		Response rsp = request.get();
+		Response rsp;
+		try {
+			rsp = request.get();
+		} catch (ProcessingException e) {
+			throw this.handleProcessingException(HttpMethod.GET, e);
+		}
 
 		// Return response message (header)
 		return rsp.readEntity(String.class);
@@ -171,7 +178,12 @@
 		Builder request = retrieveBuilder(servicePath);
 
 		// Perform request
-		Response rsp = request.put(Entity.entity(newValue, mediaType));
+		Response rsp;
+		try {
+			rsp = request.put(Entity.entity(newValue, mediaType));
+		} catch (ProcessingException e) {
+			throw this.handleProcessingException(HttpMethod.PUT, e);
+		}
 
 		// Return response message (header)
 		return rsp.readEntity(String.class);
@@ -185,7 +197,12 @@
 		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;
+		try {
+			rsp = client.target(VABPathTools.concatenatePaths(address, servicePath)).request().build("PATCH", Entity.text(newValue)).property(HttpUrlConnectorProvider.SET_METHOD_WORKAROUND, true).invoke();
+		} catch (ProcessingException e) {
+			throw this.handleProcessingException(HttpMethod.PATCH, e);
+		}
 
 		// Return response message (header)
 		return rsp.readEntity(String.class);
@@ -197,7 +214,12 @@
 		Builder request = retrieveBuilder(servicePath);
 
 		// Perform request
-		Response rsp = request.post(Entity.entity(parameter, mediaType));
+		Response rsp;
+		try {
+			rsp = request.post(Entity.entity(parameter, mediaType));
+		} catch (ProcessingException e) {
+			throw this.handleProcessingException(HttpMethod.POST, e);
+		}
 
 		// Return response message (header)
 		return rsp.readEntity(String.class);
@@ -209,7 +231,12 @@
 		Builder request = retrieveBuilder(servicePath);
 
 		// Perform request
-		Response rsp = request.delete();
+		Response rsp;
+		try {
+			rsp = request.delete();
+		} catch (ProcessingException e) {
+			throw this.handleProcessingException(HttpMethod.DELETE, e);
+		}
 
 		// Return response message (header)
 		return rsp.readEntity(String.class);
@@ -231,4 +258,17 @@
 		return buildRequest(client, VABPathTools.concatenatePaths(address, servicePath));
 	}
 
+	private ProviderException handleProcessingException(HttpMethod method, ProcessingException e) {
+		return new ProviderException("[HTTP " + method.name() + "] Failed to request " + this.address + " with mediatype " + this.mediaType);
+	}
+
+	/**
+	 * 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/server/VABHTTPInterface.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/vab/protocol/http/server/VABHTTPInterface.java
index 692305b..313a135 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,7 @@
 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 +10,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 +21,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 +94,6 @@
 	 */
 	@Override
 	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
-		PrintWriter responseWriter = resp.getWriter();
-		
 		try {
 			String path = extractPath(req);
 
@@ -103,12 +104,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 +119,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 +144,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 +156,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 +179,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 +186,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 +200,6 @@
 	 */
 	@Override
 	protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
-		PrintWriter responseWriter = resp.getWriter();
-
 		try {
 			String path = extractPath(req);
 
@@ -222,12 +209,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 +290,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/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..cc30ccc 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
@@ -8,10 +8,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 +30,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 +45,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 +70,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 +149,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 +185,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/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..0b53ac6
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/aggregator/TestAASAggregatorProxy.java
@@ -0,0 +1,86 @@
+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
+		assertTrue((boolean) ((IOperation) sm.getSubmodelElement(op.getIdShort())).invoke());
+
+		// 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/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..140cecb
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/factory/json/TestJSONConverter.java
@@ -0,0 +1,120 @@
+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.get());
+	}
+	
+	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..842f4a8 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
@@ -4,7 +4,6 @@
 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;
@@ -47,9 +46,10 @@
 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.valuetypedef.PropertyValueTypeDef;
+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;
@@ -66,101 +66,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) {
@@ -355,7 +324,7 @@
 		assertNotNull(submodel);
 		checkDefaultEmbeddedDataSpecification(submodel);
 		assertEquals("3s7plfdrs35_submodel1", submodel.getIdShort());
-		Collection<IConstraint> constraints = submodel.getQualifier();
+		Collection<IConstraint> constraints = submodel.getQualifiers();
 		assertEquals(2, constraints.size());
 		checkSubmodelElements(submodel);
 	}
@@ -370,19 +339,22 @@
 		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.get());
+		assertEquals(PropertyValueTypeDef.Double, property.getValueType());
 		assertEquals("rotationSpeed", property.getIdShort());
 		
 		element = submodelElements.get("emptyDouble");
 		assertTrue(element instanceof Property);
 		property = (Property) element;
-		assertEquals("double", property.getValueType());
+		assertEquals(PropertyValueTypeDef.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 +380,7 @@
 		element = submodelElements.get("range_id");
 		assertTrue(element instanceof Range);
 		Range range = (Range) element;
-		assertEquals("int", range.getValueType());
+		assertEquals(PropertyValueTypeDef.Integer, range.getValueType());
 		assertEquals("1", range.getMin());
 		assertEquals("10", range.getMax());
 		
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..6e661f8 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
@@ -52,7 +52,7 @@
 		InMemoryDirectory directory = new InMemoryDirectory();
 		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 +62,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);
@@ -115,7 +115,7 @@
 		// 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..5fc2233 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,13 +1,19 @@
 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.metamodel.map.descriptor.ModelUrn;
+import org.eclipse.basyx.aas.metamodel.map.parts.Asset;
 import org.eclipse.basyx.aas.registration.api.IAASRegistryService;
 import org.eclipse.basyx.aas.registration.memory.InMemoryRegistry;
 import org.eclipse.basyx.aas.restapi.AASModelProvider;
@@ -20,6 +26,8 @@
 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;
@@ -57,17 +65,16 @@
 		// Register AAS at directory
 		IIdentifier aasId = new Identifier(IdentifierType.CUSTOM, "aasId");
 		String aasIdShort = "aasName";
-		connectorProvider.addMapping("", new AASAggregatorProvider(new AASAggregator()));
-
+		IModelProvider provider = new AASAggregatorProvider(new AASAggregator());
+		prepareConnectorProvider(provider);
+ 
 		// Create an AAS containing a reference to the created SubModel
-		AssetAdministrationShell aas = new AssetAdministrationShell();
-		aas.setIdentification(aasId);
-		aas.setIdShort(aasIdShort);
-		manager.createAAS(aas, aasId, "");
+		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,6 +83,7 @@
 		assertEquals(aasId.getIdType(), connectedAAS.getIdentification().getIdType());
 	}
 
+
 	@Test
 	public void testCreateSubModel() throws Exception {
 		IIdentifier aasId = new Identifier(IdentifierType.CUSTOM, "aasId");
@@ -114,9 +122,124 @@
 		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) {
+		VABElementProxy proxy = new VABElementProxy("/shells", provider);
+		connectorProvider.addMapping("shells", proxy);
+		connectorProvider.addMapping("", proxy);
+	}
+
+	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..da56305 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
@@ -5,11 +5,14 @@
 
 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.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;
@@ -25,6 +28,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.property.Property;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetypedef.PropertyValueTypeDef;
 import org.junit.Test;
 
 
@@ -72,9 +76,7 @@
 		 * implicitly
 		 */
 		// Create an AAS containing a reference to the created SubModel
-		AssetAdministrationShell aas = new AssetAdministrationShell();
-		aas.setIdShort(AASIDSHORT);
-		aas.setIdentification(AASID);
+		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);
@@ -100,10 +102,8 @@
 		Property p = new Property(PROPVAL);
 		p.setIdShort(PROPID);
 
-		SubModel sm = new SubModel();
+		SubModel sm = new SubModel(SMIDSHORT, SMID);
 		sm.addSubModelElement(p);
-		sm.setIdShort(SMIDSHORT);
-		sm.setIdentification(SMID.getIdType(), SMID.getId());
 
 		return sm;
 	}
@@ -142,7 +142,7 @@
 		// Check if the submodel has been retrieved correctly
 		ISubModel sm = shell.getSubModels().get(SMIDSHORT);
 		IProperty prop = sm.getProperties().get(PROPID);
-		assertEquals(PROPVAL, prop.get());
+		assertEquals(PROPVAL, prop.getValue());
 	}
 
 	/**
@@ -167,9 +167,10 @@
 		// 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", PropertyValueTypeDef.String);
+		prop.setValue("testProperty");
+		subModel.addSubModelElement(prop);
 		
 		//Retrieve the aas
 		IAssetAdministrationShell shell = retrieveShell();
@@ -184,7 +185,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..ef6c8c2 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,5 +1,8 @@
 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;
@@ -10,12 +13,15 @@
 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.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
@@ -36,14 +42,14 @@
 
 		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();
 		// 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 +71,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..547e339
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/TestAasEnv.java
@@ -0,0 +1,95 @@
+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.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.map.SubModel;
+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.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");
+		
+		Map<String, Object> assetAdministrationShell = new HashMap<>();
+		assetAdministrationShell.put(ModelType.MODELTYPE, AssetAdministrationShell.MODELTYPE);
+		assetAdministrationShell.put(Referable.IDSHORT, "TestAssetAdministrationShell");
+
+		Map<String, Object> submodel = new HashMap<>();
+		submodel.put(ModelType.MODELTYPE, SubModel.MODELTYPE);
+		submodel.put(Referable.IDSHORT, "TestSubmodel");
+		submodel.put(SubModel.SUBMODELELEMENT, new ArrayList<Object>());
+		
+		Map<String, Object> conceptDescription = new HashMap<>();
+		submodel.put(ModelType.MODELTYPE, ConceptDescription.MODELTYPE);
+		submodel.put(Referable.IDSHORT, "TestConceptDescription");
+		
+		
+		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..0ded0b6 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
@@ -6,7 +6,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;
 
@@ -22,10 +21,12 @@
 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.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.valuetypedef.PropertyValueTypeDef;
 import org.eclipse.basyx.testsuite.regression.aas.metamodel.AssetAdministrationShellSuite;
 import org.junit.Before;
 import org.junit.Test;
@@ -63,17 +64,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);
@@ -119,12 +109,15 @@
 	@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", PropertyValueTypeDef.String);
+		prop1.setValue("testProperty1");
+		subModel1.addSubModelElement(prop1);
+
+		SubModel subModel2 = new SubModel("newSubmodelId2", new Identifier(IdentifierType.CUSTOM, "smId2"));
+		Property prop2 = new Property("prop2Id", PropertyValueTypeDef.String);
+		prop2.setValue("testProperty2");
+		subModel2.addSubModelElement(prop2);
 		
 		// create a collection of descriptors and add the above descriptors
 		Collection<SubModel> submodels = new ArrayList<SubModel>();
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..59e31ae 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,22 @@
 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.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,6 +26,17 @@
  *
  */
 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(AssetAdministrationShell.ENDPOINTS, Arrays.asList(new HashMap<String, String>()));
+		map.put(AssetAdministrationShell.SUBMODELS, new HashSet<SubmodelDescriptor>());
+	}
 
 	/**
 	 * Tests retrieval of all registered submodel descriptors
@@ -35,4 +57,76 @@
 		// Assert correct retrieval
 		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(AssetAdministrationShell.ENDPOINTS);
+		new AASDescriptor(map);
+	}
+	
+	@Test(expected = MalformedRequestException.class)
+	public void testValidateNullEndpoints() {
+		map.put(AssetAdministrationShell.ENDPOINTS, null);
+		new AASDescriptor(map);
+	}
+	
+	@Test(expected = MalformedRequestException.class)
+	public void testValidateWrongEndpoints() {
+		map.put(AssetAdministrationShell.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/TestSubmodelDescriptor.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/descriptor/TestSubmodelDescriptor.java
index 55adcb4..49a7e73 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
@@ -31,7 +31,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);
 	
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 f64cbc7..60ea076 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
@@ -45,8 +45,8 @@
 	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;
 	/**
@@ -152,6 +152,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 +201,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 +208,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,20 +223,6 @@
 		} catch (ResourceNotFoundException e) {
 			// expected
 		}
-
-		// 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
-		}
 	}
 
 	/**
@@ -239,12 +252,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");
+		proxy.delete(aasId1, new Identifier(IdentifierType.CUSTOM, "nonExistentSubModelId"));
 	}
 
 	@Test(expected = ResourceNotFoundException.class)
@@ -252,12 +265,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());
@@ -277,17 +303,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/restapi/MultiAASProviderTest.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/restapi/MultiAASProviderTest.java
index a37c034..801b73b 100644
--- 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
@@ -4,16 +4,13 @@
 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.metamodel.map.submodelelement.operation.Operation;
+import org.eclipse.basyx.submodel.restapi.MultiSubmodelElementProvider;
 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;
@@ -37,7 +34,7 @@
 		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()));
+		aasProvider.addSubmodel(new SubModelProvider(new SimpleAASSubmodel()));
 		provider = new MultiAASProvider();
 		provider.addMultiSubmodelProvider("a1", aasProvider);
 		stub.addProvider(urn, "", provider);
@@ -47,50 +44,61 @@
 	@Test
 	public void clearTest() {
 		provider.clear();
-		Object result = proxy.getModelPropertyValue("a1/aas/submodels/SimpleAASSubmodel/");
-		assertNull(result);
+		
+		// test if AAS is deleted
+		try {
+			proxy.getModelPropertyValue("a1/aas/submodels/SimpleAASSubmodel/");
+			fail();
+		} catch(ResourceNotFoundException e) {}
 	}
 
-	@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));
+		Integer result = (Integer) proxy
+				.getModelPropertyValue("a1/aas/submodels/SimpleAASSubmodel/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/integerProperty/value");
+		assertEquals(123, result.intValue());
 
 		// test reading from an invalid aas
-		assertNull(proxy.getModelPropertyValue("A1/aas/submodels/SimpleAASSubmodel/"));
+		try {
+			proxy.getModelPropertyValue("A1/aas/submodels/SimpleAASSubmodel/submodel");
+			fail();
+		} catch(ResourceNotFoundException e) {}
 	}
 
-	@SuppressWarnings("unchecked")
 	@Test
 	public void setTest() {
 		// test setting in a valid aas
-		proxy.setModelPropertyValue("a1/aas/submodels/SimpleAASSubmodel/" + SubmodelElementProvider.PROPERTIES + "/integerProperty/value", 100);
+		proxy.setModelPropertyValue("a1/aas/submodels/SimpleAASSubmodel/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/integerProperty/value", 100);
 
 		// test setting in an invalid aas
-		proxy.setModelPropertyValue("A1/aas/submodels/SimpleAASSubmodel/" + SubmodelElementProvider.PROPERTIES + "/integerProperty/value", 200);
+		try {
+			proxy.setModelPropertyValue("A1/aas/submodels/SimpleAASSubmodel/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/integerProperty/value", 200);
+			fail();
+		} catch(ResourceNotFoundException e) {}
 
 		// 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));
+		Integer result = (Integer) proxy
+				.getModelPropertyValue("a1/aas/submodels/SimpleAASSubmodel/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/integerProperty/value");
+		assertEquals(100, result.intValue());
 	}
 
-	@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));
+		try {
+			proxy.deleteValue("A1/aas/submodels/SimpleAASSubmodel/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/integerProperty/value");
+			fail();
+		} catch(ResourceNotFoundException e) {}
+		
+		Integer result = (Integer) proxy
+				.getModelPropertyValue("a1/aas/submodels/SimpleAASSubmodel/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/integerProperty/value");
+		assertEquals(123, result.intValue());
 
 		// test deleting from a valid aas
-		proxy.deleteValue("a1/aas/submodels/SimpleAASSubmodel/" + SubmodelElementProvider.PROPERTIES + "/integerProperty");
+		proxy.deleteValue("a1/aas/submodels/SimpleAASSubmodel/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/integerProperty");
 		try {
-			proxy.getModelPropertyValue("a1/aas/submodels/SimpleAASSubmodel/" + SubmodelElementProvider.PROPERTIES + "/integerProperty/");
+			proxy.getModelPropertyValue("a1/aas/submodels/SimpleAASSubmodel/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/integerProperty/");
 			fail();
 		} catch (ResourceNotFoundException e) {
 		}
@@ -100,14 +108,14 @@
 	public void invokeExceptionTest() {
 		// Invoke exception1
 		try {
-			proxy.invokeOperation("a1/aas/submodels/SimpleAASSubmodel/operations/exception1");
+			proxy.invokeOperation("a1/aas/submodels/SimpleAASSubmodel/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/exception1/" + Operation.INVOKE);
 			fail();
 		} catch (ProviderException e) {
 			assertEquals(NullPointerException.class, e.getCause().getClass());
 		}
 		// Invoke exception2
 		try {
-			proxy.invokeOperation("a1/aas/submodels/SimpleAASSubmodel/operations/exception2", "prop1");
+			proxy.invokeOperation("a1/aas/submodels/SimpleAASSubmodel/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/exception2/" + Operation.INVOKE, "prop1");
 			fail();
 		} catch (ProviderException e) {
 			assertEquals("Exception description", e.getMessage());
@@ -117,10 +125,13 @@
 	@Test
 	public void invokeTest() {
 		// test invoking from an invalid aas
-		assertNull(proxy.invokeOperation("A1/aas/submodels/SimpleAASSubmodel/operations/complex", 10, 3));
+		try {
+			proxy.invokeOperation("A1/aas/submodels/SimpleAASSubmodel/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/complex/" + Operation.INVOKE, 10, 3);
+			fail();
+		} catch(ResourceNotFoundException e) {}
 
 		// 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"));
+		assertEquals(7, proxy.invokeOperation("a1/aas/submodels/SimpleAASSubmodel/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/complex/" + Operation.INVOKE, 10, 3));
+		assertEquals(true, proxy.invokeOperation("a1/aas/submodels/SimpleAASSubmodel/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/simple/" + Operation.INVOKE));
 	}
 }
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..2069216
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/restapi/MultiSubmodelProviderRemoteInvocationTest.java
@@ -0,0 +1,192 @@
+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 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.IAASRegistryService;
+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.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.modelprovider.VABPathTools;
+import org.eclipse.basyx.vab.protocol.basyx.connector.BaSyxConnectorProvider;
+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 VABMultiSubmodelProvider provider;
+
+	@Before
+	public void init() {
+		// Creating a new AAS Registry
+		IAASRegistryService registry = new InMemoryRegistry();
+		
+		
+		// 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 VABMultiSubmodelProvider(registry, new BaSyxConnectorProvider());
+		
+		// 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.getModelPropertyValue("/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);
+	}
+
+	/**
+	 * 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.setModelPropertyValue(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.setModelPropertyValue(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.getModelPropertyValue(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..fd10b96 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.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.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.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;
@@ -48,12 +51,11 @@
 		VABConnectionManagerStub stub = new VABConnectionManagerStub();
 		String urn = "urn:fhg:es.iese:aas:1:1:submodel";
 		VABMultiSubmodelProvider provider = new VABMultiSubmodelProvider();
+
 		// 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,8 +81,8 @@
 	@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")
@@ -96,12 +98,12 @@
 	public void createDeleteSubmodelTest() {
 		SubModel sm = new SimpleAASSubmodel("TestSM");
 		sm.setIdentification(IdentifierType.CUSTOM, "TestId");
-		proxy.createValue("/aas/submodels", sm);
+		proxy.setModelPropertyValue("/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());
@@ -120,15 +122,14 @@
 		}
 	}
 
-	@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
+				.getModelPropertyValue("/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.getModelPropertyValue("/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..021c22b 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
@@ -32,7 +32,7 @@
 		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/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..86db069
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/TestSubmodelSuite.java
@@ -0,0 +1,347 @@
+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.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.IBlob;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.relationship.IRelationshipElement;
+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.dataelement.property.valuetypedef.PropertyValueTypeDef;
+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 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));
+
+	public SubModel getReferenceSubmodel() {
+
+		// Create a simple value property
+		Property propertyMeta = new Property(PROP, PropertyValueTypeDef.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.get(), 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(3, values.size());
+
+		// Check if all expected Values are present
+		assertEquals(100, values.get(PROP));
+
+		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(BLOB_ID));
+	}
+
+	/**
+	 * 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);
+
+		Property byteProp = new Property();
+		byteProp.setIdShort("byte_prop01");
+		Byte byteNumber = Byte.parseByte("2");
+		byteProp.set(byteNumber);
+		ret.put(byteProp.getIdShort(), byteProp);
+
+		Property durationProp = new Property();
+		durationProp.setIdShort("duration_prop01");
+		Duration duration = Duration.ofSeconds(10);
+		durationProp.set(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.set(p);
+		ret.put(periodProp.getIdShort(), periodProp);
+
+		Property bigNumberProp = new Property();
+		bigNumberProp.setIdShort("bignumber_prop01");
+		BigInteger bignumber = new BigInteger("9223372036854775817");
+		property.set(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 Blob to use as Value for smECollection
+		Blob blob = new Blob(BLOB_ID, "text/json");
+		blob.setValue(new byte[] { 1, 2, 3 });
+
+		List<ISubmodelElement> values = new ArrayList<>();
+		values.add(blob);
+
+		smECollection.setValue(values);
+		ret.put(smECollection.getIdShort(), smECollection);
+
+		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);
+
+		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 acutalProperty = (IProperty) actual.get(PROPERTY_ID);
+			assertNotNull(acutalProperty);
+			try {
+				assertEquals(expectedProperty.getValue(), acutalProperty.getValue());
+				assertEquals(expectedProperty.getValueType(), acutalProperty.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
+		for (ISubmodelElement iSubmodelElement : elements) {
+			assertTrue(iSubmodelElement instanceof IBlob);
+		}
+
+		assertEquals(expectedCollection.getSubmodelElements().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());
+	}
+
+	/**
+	 * 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/connected/TestConnectedProperty.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/TestConnectedProperty.java
index 5fceb14..698f91b 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
@@ -8,7 +8,7 @@
 import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.dataelement.ConnectedProperty;
 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.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;
@@ -31,7 +31,7 @@
 		// Create PropertySingleValued containing the simple value
 		Property propertyMeta = new Property(VALUE);
 		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
@@ -40,10 +40,10 @@
 		propertyMeta.setValueType(PropertyValueTypeDef.String);
 		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());
+		assertEquals("content", prop.getValue());
 	}
 
 	/**
@@ -53,7 +53,7 @@
 	 */
 	@Test
 	public void testGet() throws Exception {
-		int val = (int) prop.get();
+		int val = (int) prop.getValue();
 		assertEquals(VALUE, val);
 	}
 
@@ -64,8 +64,8 @@
 	 */
 	@Test
 	public void testValueTypeRetrieval() {
-		String valueType = prop.getValueType();
-		assertEquals(PropertyValueTypeDef.Integer.toString(), valueType);
+		PropertyValueTypeDef valueType = prop.getValueType();
+		assertEquals(PropertyValueTypeDef.Integer, valueType);
 	}
 
 	/**
@@ -76,7 +76,7 @@
 	@Test
 	public void testSet() throws Exception {
 		prop.set(123);
-		int val = (int) prop.get();
+		int val = (int) prop.getValue();
 		assertEquals(123, val);
 	}
 
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
index 3a1580e..c24f6a2 100644
--- 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
@@ -1,36 +1,21 @@
 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.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.TypeDestroyingProvider;
@@ -38,80 +23,40 @@
 import org.junit.Test;
 
 /**
- * Tests if a SubModel can be created and used correctly
+ * Tests if a ConnectSubmodel can be created and used correctly
  *
  * @author schnicke
  *
  */
-public class TestConnectedSubModel {
+public class TestConnectedSubModel extends TestSubmodelSuite {
 
 	// 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));
+	private final String OPERATION_ID = "operation_id";
 
 	ConnectedSubModel submodel;
 
 	@Before
 	public void build() {
-		// Create a simple value property
-		Property propertyMeta = new Property(100);
-		propertyMeta.setIdShort(PROP);
 
+		SubModel reference = getReferenceSubmodel();
 		// Create an operation
 		Operation op = new Operation((Function<Object[], Object> & Serializable) obj -> {
 			return (int) obj[0] + (int) obj[1];
 		});
 		op.setIdShort(OP);
+		reference.addSubModelElement(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)));
+		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 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
@@ -126,206 +71,57 @@
 		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()) {
+		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);
+	public void testGetLocalCopy() {
+		assertEquals(getReferenceSubmodel(), submodel.getLocalCopy());
 	}
-	
-	/**
-	 * 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());
+
+	@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..f025c26 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
@@ -2,17 +2,22 @@
 
 import static org.junit.Assert.assertEquals;
 
+import java.util.ArrayList;
+import java.util.Collection;
 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.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.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 +34,7 @@
 	private static final String PROP = "prop";
 	private static final String OPERATION = "sum";
 
-	ISubmodelElementCollection prop;
+	ConnectedSubmodelElementCollection prop;
 
 	@Before 
 	public void build() {
@@ -45,17 +50,21 @@
 
 		// Create ComplexDataProperty containing the created operation and property
 		SubmodelElementCollection complex = new SubmodelElementCollection();
-		complex.addElement(propertyMeta);
-		complex.addElement(operation);
+		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 +84,7 @@
 		IProperty prop = props.get(PROP);
 
 		// Check contained values
-		assertEquals(4, prop.get());
+		assertEquals(4, prop.getValue());
 	}
 
 	/**
@@ -95,4 +104,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..32b73ab 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
@@ -25,14 +25,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.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.MultiSubmodelElementProvider;
 import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
 import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaProvider;
 import org.eclipse.basyx.vab.support.TypeDestroyingProvider;
@@ -76,8 +76,6 @@
 		
 		Map<String, Object> values = new HashMap<>();
 		
-		values.put(SubmodelElementProvider.PROPERTIES, dataElements);
-		values.put(SubmodelElementProvider.OPERATIONS, operations);
 		values.put(SubModel.SUBMODELELEMENT, submodelElements);
 		
 		proxy = new VABElementProxy("", new SubModelProvider(new TypeDestroyingProvider(new VABLambdaProvider(values))));
@@ -161,7 +159,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 +172,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);
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..ccf3dd4 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
@@ -8,7 +8,7 @@
 
 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;
@@ -33,7 +33,7 @@
 		blob.setMimeType("mimeType");
 		
 		VABConnectionManagerStub manager = new VABConnectionManagerStub(
-				new PropertyProvider(new TypeDestroyingProvider(new VABLambdaProvider(blob))));
+				new SubmodelElementProvider(new TypeDestroyingProvider(new VABLambdaProvider(blob))));
 
 		connectedBlob = new ConnectedBlob(manager.connectToVABElement(""));
 	}
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..5821c60 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
@@ -4,7 +4,7 @@
 
 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;
@@ -29,7 +29,7 @@
 		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 +50,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..77e1987 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
@@ -9,7 +9,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 +36,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..6474af1 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
@@ -3,8 +3,10 @@
 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.valuetypedef.PropertyValueTypeDef;
+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 +26,10 @@
 	
 	@Before
 	public void build() {
-		range = new Range("valueType", new Integer(1), new Integer(10));
+		range = new Range(PropertyValueTypeDef.Integer, new Integer(1), new Integer(10));
 		
 		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 +57,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..85fe35d 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
@@ -8,7 +8,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 +34,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(""));
 	}
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..da6bca5 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
@@ -8,7 +8,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 +34,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..c262015 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,16 @@
 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 +19,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/TestConnectedRelationshipElement.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/relationship/TestConnectedRelationshipElement.java
index 95dd6a3..8fff134 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
@@ -8,7 +8,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.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 +36,7 @@
 		
 		
 		VABConnectionManagerStub manager = new VABConnectionManagerStub(
-				new PropertyProvider(new TypeDestroyingProvider(new VABLambdaProvider(relElem))));
+				new SubmodelElementProvider(new TypeDestroyingProvider(new VABLambdaProvider(relElem))));
 
 		connectedRelElem = new ConnectedRelationshipElement(manager.connectToVABElement(""));
 	}
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..6ec3506
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/facade/TestSubmodelElementMapCollectionConverter.java
@@ -0,0 +1,70 @@
+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.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();
+		property.setIdShort(ID_SHORT);
+		
+		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..d52f739 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
@@ -3,26 +3,20 @@
 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.submodel.metamodel.api.identifier.IdentifierType;
-import org.eclipse.basyx.submodel.metamodel.api.qualifier.haskind.ModelingKind;
+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.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.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.testsuite.regression.submodel.metamodel.TestSubmodelSuite;
+import org.junit.Before;
 import org.junit.Test;
 
 /**
@@ -31,38 +25,25 @@
  * @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", PropertyValueTypeDef.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());
 	} 
 
 	/**
@@ -87,4 +68,9 @@
 		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/qualifier/TestLangStrings.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestLangStrings.java
index 5f02fb9..89edc55 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,8 @@
 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 +77,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/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..408b67f 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
@@ -29,7 +29,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 +39,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..6f58b0c 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
@@ -7,6 +7,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.valuetypedef.PropertyValueTypeDef;
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetypedef.PropertyValueTypeDefHelper;
 import org.junit.Before;
 import org.junit.Test;
 
@@ -22,7 +24,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 +40,7 @@
 	public void testConstructor() {
 		assertEquals(TYPE, qualifier.getType());
 		assertEquals(VALUE, qualifier.getValue());
-		assertEquals(VALUE_TYPE, qualifier.getValueType());
+		assertEquals(PropertyValueTypeDefHelper.fromName(VALUE_TYPE), qualifier.getValueType());
 		assertEquals(VALUE_ID, qualifier.getValueId());
 	}
 	
@@ -65,7 +67,7 @@
 	
 	@Test
 	public void testSetValueType() {
-		String newValueTypeString = "newValueType";
+		PropertyValueTypeDef newValueTypeString = PropertyValueTypeDef.AnyType;
 		qualifier.setValueType(newValueTypeString);
 		assertEquals(newValueTypeString, qualifier.getValueType());
 	}
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..81b3c7d 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,7 @@
 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 +84,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..cb11931 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,8 @@
 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 +79,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/TestSubmodelmodelElement.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/TestSubmodelElement.java
similarity index 94%
rename from sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/TestSubmodelmodelElement.java
rename to sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/TestSubmodelElement.java
index 226081f..f1df49b 100644
--- 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/TestSubmodelElement.java
@@ -28,7 +28,7 @@
  * @author haque
  *
  */
-public class TestSubmodelmodelElement {
+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))));
 	
@@ -36,8 +36,7 @@
 	
 	@Before
 	public void buidSubmodelElement() {
-		Property property = new Property("testId");
-		submodelElement = SubmodelElement.createAsFacade(property);
+		submodelElement = new Property("testId");
 	}
 	
 	@Test
@@ -84,8 +83,8 @@
 	
 	@Test
 	public void testSetQualifier() {
-		submodelElement.setQualifier(Collections.singleton(FORMULA));
-		assertEquals(Collections.singleton(FORMULA), submodelElement.getQualifier());
+		submodelElement.setQualifiers(Collections.singleton(FORMULA));
+		assertEquals(Collections.singleton(FORMULA), submodelElement.getQualifiers());
 	}
 	
 	@Test
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..66a632a 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
@@ -28,6 +28,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;
 
@@ -64,15 +65,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 +91,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
@@ -136,17 +146,45 @@
 	@Test
 	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
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..694bf1c 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
@@ -2,8 +2,12 @@
 
 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;
@@ -21,6 +25,7 @@
 import org.junit.Before;
 import org.junit.Test;
 
+
 /**
  * Tests constructor, getter and setter of {@link Property} for their
  * correctness
@@ -30,7 +35,7 @@
  */
 public class TestProperty {
 	private static final String VALUE = "testValue";
-	private static final String STRING_TYPE = "string";
+	private static final PropertyValueTypeDef STRING_TYPE = PropertyValueTypeDef.String;
 	private Property property;
 
 	@Before
@@ -39,14 +44,14 @@
 	}
 	
 	@Test
-	public void testConstructor1() {
+	public void testConstructor1(){
 		assertEquals(VALUE, property.get());
 		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)))));
@@ -63,35 +68,46 @@
 	} 
 	
 	@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.set(isSomething);
+		assertEquals(isSomething, booleanProp.get());
+		assertEquals(isSomething, booleanProp.getValue());
+		assertEquals(PropertyValueTypeDef.Boolean, booleanProp.getValueType());
+
+		Byte byteNumber = new Byte("2");
+		Property byteProp = new Property();
+		byteProp.set(byteNumber);
+		assertEquals(byteNumber, byteProp.get());
+		assertEquals(PropertyValueTypeDef.Int8, byteProp.getValueType());
+		
+		Duration duration = Duration.ofSeconds(10);
+		Property durationProp = new Property();
+		durationProp.set(duration);
+		assertEquals(duration, durationProp.get());
+		assertEquals(PropertyValueTypeDef.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.set(p);
+		assertEquals(p, periodProp.get());
+		assertEquals(PropertyValueTypeDef.YearMonthDuration, periodProp.getValueType());
+
+		Property bigNumberProp = new Property();
+		BigInteger bignumber = new BigInteger("9223372036854775817");
+		bigNumberProp.set(bignumber);
+		assertEquals(bignumber, bigNumberProp.get());
+		assertEquals(PropertyValueTypeDef.PositiveInteger, bigNumberProp.getValueType());
 	}
 
 	@Test
-	public void testSetCustom() {
+	public void testSetCustom(){
 		property.set(null, PropertyValueTypeDef.String);
 		assertEquals(null, property.get());
-		assertEquals(PropertyValueTypeDef.String.getStandardizedLiteral(), property.getValueType());
+		assertEquals(PropertyValueTypeDef.String, property.getValueType());
 	}
 
 	@Test
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..f42434f
--- /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,39 @@
+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.valuetypedef.PropertyValueTypeDef;
+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(PropertyValueTypeDef.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..89e0934
--- /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,74 @@
+package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.submodelelement.operation;
+
+import java.util.function.Function;
+
+import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation;
+
+/**
+ * Helperclass for testing async invocations of Operations
+ * 
+ * @author conradi
+ *
+ */
+public class AsyncOperationHelper {
+	
+	public static final String ASYNC_OP_ID = "asyncOperation";
+	public static final String ASYNC_EXCEPTION_OP_ID = "asyncExceptionOperation";
+
+	private Object waitObject = new Object();
+	private boolean shouldWait = true;
+	
+	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);
+		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(10);
+		} 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..1724d93 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
@@ -10,108 +10,60 @@
 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);
+		
 		assertEquals(1, operation.invoke(3,2));
 	}
 	
 	@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..aa81f1a
--- /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,141 @@
+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.Collections;
+import java.util.function.Function;
+
+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.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.OperationVariable;
+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 final Collection<OperationVariable> IN = Collections.singletonList(new OperationVariable(new Property(IN_VALUE)));
+	protected static final Collection<OperationVariable> OUT = Collections.singletonList(new OperationVariable(new Property(OUT_VALUE)));
+	protected static final Collection<OperationVariable> INOUT = Collections.singletonList(new OperationVariable(new Property(INOUT_VALUE)));
+	
+	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() {
+		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 {
+			operationException.invoke();
+			fail();
+		} catch (Exception e) {
+			// Exceptions from ConnectedOperation are wrapped in ProviderException
+			assertTrue(e instanceof NullPointerException
+					|| e.getCause() instanceof NullPointerException);
+		}
+	}
+	
+	@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 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() {
+		Object value = getValueFromOpVariable(operation.getInputVariables());
+		assertEquals(IN_VALUE, value);
+	}
+
+	@Test
+	public void testOutputVariables() {
+		Object value = getValueFromOpVariable(operation.getOutputVariables());
+		assertEquals(OUT_VALUE, value);
+	}
+
+	@Test
+	public void testInOutputVariables() {
+		Object value = getValueFromOpVariable(operation.getInOutputVariables());
+		assertEquals(INOUT_VALUE, value);
+	}
+	
+	/**
+	 * Gets the Value from the OperationVariable in a collection
+	 */
+	private Object getValueFromOpVariable(Collection<IOperationVariable> vars) {
+		assertEquals(1, vars.size());
+		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/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..cdc2d1f 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
@@ -8,6 +8,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 +48,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..9865d18 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
@@ -6,7 +6,7 @@
 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.restapi.SubmodelElementProvider;
 import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
 import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaProvider;
 import org.junit.Test;
@@ -31,11 +31,11 @@
 		});
 		
 		// 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();
+		PropertyValueTypeDef expectedType = PropertyValueTypeDef.Double;
 		assertEquals(expectedType, connectedProperty.getValueType());
 		
 		// Check value is correctly retrievable by property
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..4d7bb8d 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
@@ -2,6 +2,7 @@
 
 import java.util.function.Function;
 
+import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
 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;
@@ -16,6 +17,10 @@
  *
  */
 public class SimpleAASSubmodel extends SubModel {
+
+	public static final String INTPROPIDSHORT = "integerProperty";
+	public static final String OPERATIONSIMPLEIDSHORT = "simple";
+
 	public SimpleAASSubmodel() {
 		this("SimpleAASSubmodel");
 	}
@@ -27,9 +32,10 @@
 		// Create sub model
 
 		setIdShort(idShort);
+		setIdentification(new ModelUrn("simpleAASSubmodelUrn"));
 
 		Property intProp = new Property(123);
-		intProp.setIdShort("integerProperty");
+		intProp.setIdShort(INTPROPIDSHORT);
 		addSubModelElement(intProp);
 
 		Property stringProp = new Property("Test");
@@ -50,7 +56,7 @@
 		Operation simple = new Operation((Function<Object[], Object>) v -> {
 			return true;
 		});
-		simple.setIdShort("simple");
+		simple.setIdShort(OPERATIONSIMPLEIDSHORT);
 		addSubModelElement(simple);
 
 		// Create example operations
@@ -68,13 +74,19 @@
 		exception2.setIdShort("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);
+		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
index 3a6a7c4..c87cf69 100644
--- 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
@@ -1,30 +1,41 @@
 package org.eclipse.basyx.testsuite.regression.submodel.restapi;
 
 import static org.junit.Assert.assertEquals;
+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.valuetypedef.PropertyValueTypeDefHelper;
+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.SubmodelElementProvider;
+import org.eclipse.basyx.submodel.restapi.operation.OperationResult;
+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.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 static final String submodelAddr = "urn:fhg:es.iese:aas:1:1:submodel";
 
 	protected VABConnectionManager getConnectionManager() {
 		if (connManager == null) {
@@ -60,7 +71,6 @@
 	/**
 	 * Test creating single property
 	 */
-	@SuppressWarnings("unchecked")
 	@Test
 	public void testCreateProperty() {
 		VABElementProxy submodelElement = getConnectionManager().connectToVABElement(submodelAddr);
@@ -68,12 +78,38 @@
 		// Create element
 		Property prop = new Property(500);
 		prop.setIdShort("newProperty");
-		submodelElement.createValue("/submodel/" + SubmodelElementProvider.PROPERTIES + "", prop);
+		submodelElement.setModelPropertyValue("/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/newProperty", prop);
 
 		// Read back value
-		Map<String, Object> result = (Map<String, Object>) submodelElement
-				.getModelPropertyValue("/submodel/" + SubmodelElementProvider.PROPERTIES + "/newProperty/value");
-		assertEquals(500, result.get(Property.VALUE));
+		Integer result = (Integer) submodelElement
+				.getModelPropertyValue("/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/newProperty/value");
+		assertEquals(500, 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.setModelPropertyValue("/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/containerRoot/newProperty", prop);
+		
+		// Read back value
+		Integer result = (Integer) submodelElement
+				.getModelPropertyValue("/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/containerRoot/newProperty/value");
+		assertEquals(500, result.intValue());
+
+
+		submodelElement.setModelPropertyValue("/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/containerRoot/container/newProperty", prop);
+
+		// Read back value
+		result = (Integer) submodelElement
+				.getModelPropertyValue("/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/containerRoot/container/newProperty/value");
+		assertEquals(500, result.intValue());
 	}
 
 	/**
@@ -85,36 +121,49 @@
 		VABElementProxy submodelElement = getConnectionManager().connectToVABElement(submodelAddr);
 
 		// Read list of properties
-		Object result = submodelElement.getModelPropertyValue("/submodel/" + SubmodelElementProvider.PROPERTIES + "");
+		Object result = submodelElement.getModelPropertyValue("/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.getModelPropertyValue("/submodel/" + SubmodelElementProvider.PROPERTIES + "/integerProperty");
+		result = submodelElement.getModelPropertyValue("/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/integerProperty");
 		property = (Map<String, Object>) result;
 		assertEquals(123, property.get(Property.VALUE));
 
 		// Read idShort
-		result = submodelElement.getModelPropertyValue("/submodel/" + SubmodelElementProvider.PROPERTIES + "/stringProperty");
+		result = submodelElement.getModelPropertyValue("/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/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));
+		String resString = (String) submodelElement
+				.getModelPropertyValue("/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/stringProperty/value");
+		assertEquals("Test", resString);
 
 		// Read null value
-		resMap = (Map<String, Object>) submodelElement
-				.getModelPropertyValue("/submodel/" + SubmodelElementProvider.PROPERTIES + "/nullProperty/value");
-		assertEquals(null, resMap.get(Property.VALUE));
+		Object resObject = submodelElement
+				.getModelPropertyValue("/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/nullProperty/value");
+		assertEquals(null, resObject);
 
 		// 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)));
+		
+		// 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")).get());
 
 		// Read nested property
 		String pathToNestedContainer = "/submodel/submodelElements/containerRoot/container";
@@ -132,41 +181,63 @@
 	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);
+		submodelElement.setModelPropertyValue("/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/integerProperty/value", 3);
 
 		// Check result
 		Map<String, Object> result = (Map<String, Object>) submodelElement
-				.getModelPropertyValue("/submodel/" + SubmodelElementProvider.PROPERTIES + "/integerProperty");
+				.getModelPropertyValue("/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/integerProperty");
 		assertEquals(3, result.get(Property.VALUE));
 	}
-
+	
 	/**
-	 * Test reading all properties of the submodel
+	 * Test updating a SubmodelElementCollection
 	 */
 	@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());
+	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.setModelPropertyValue(path + "/value", smElements);
+		
+		// read back the collection
+		Map<String, Object> map = (Map<String, Object>) submodelElement
+				.getModelPropertyValue(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 reading all operations of the submodel
+	 * Test updating a Property inside a SubmodelElementCollection 
 	 */
-	@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());
+	public void testUpdateElementInSmElementCollection() {
+		VABElementProxy submodelElement = getConnectionManager().connectToVABElement(submodelAddr);
+
+		String path = VABPathTools.concatenatePaths("submodel", MultiSubmodelElementProvider.ELEMENTS,
+				"containerRoot", "container", "integerProperty", "value");
+
+		Integer value = (Integer) submodelElement.getModelPropertyValue(path);
+		assertEquals(123, value.intValue());
+
+		submodelElement.setModelPropertyValue(path, 321);
+
+		value = (Integer) submodelElement.getModelPropertyValue(path);
+		assertEquals(321, value.intValue());
 	}
 
 	/**
@@ -176,8 +247,27 @@
 	@Test
 	public void testReadSingleOperation() {
 		VABElementProxy submodel = getConnectionManager().connectToVABElement(submodelAddr);
-		Map<String, Object> operation = (Map<String, Object>) submodel.getModelPropertyValue("/submodel/operations/simple");
+		Map<String, Object> operation = (Map<String, Object>) submodel.getModelPropertyValue("/submodel/submodelElements/simple");
 		assertEquals("simple", operation.get(Identifiable.IDSHORT));
+		
+		try {
+			submodel.getModelPropertyValue("/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.getModelPropertyValue("/submodel");
+		Object o = smMap.get(SubModel.SUBMODELELEMENT);
+		assertTrue(o instanceof Collection<?>);
 	}
 
 	/**
@@ -200,11 +290,11 @@
 		VABElementProxy submodelElement = getConnectionManager().connectToVABElement(submodelAddr);
 
 		// Delete property
-		submodelElement.deleteValue("/submodel/" + SubmodelElementProvider.PROPERTIES + "/integerProperty");
+		submodelElement.deleteValue("/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/integerProperty");
 
 		// Test, if it has been deleted
 		try {
-			submodelElement.getModelPropertyValue("/submodel/" + SubmodelElementProvider.PROPERTIES + "/integerProperty");
+			submodelElement.getModelPropertyValue("/submodel/" + MultiSubmodelElementProvider.ELEMENTS + "/integerProperty");
 			fail();
 		} catch (ResourceNotFoundException e) {}
 	}
@@ -217,11 +307,51 @@
 		VABElementProxy submodelElement = getConnectionManager().connectToVABElement(submodelAddr);
 
 		// Delete operation
-		submodelElement.deleteValue("/submodel/operations/simple");
+		submodelElement.deleteValue("/submodel/submodelElements/simple");
 
 		// Test, if it has been deleted
 		try {
-			submodelElement.getModelPropertyValue("/submodel/operations/simple");
+			submodelElement.getModelPropertyValue("/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.getModelPropertyValue(path));
+
+		// Delete property
+		submodelElement.deleteValue(path);
+		
+		// Test if parent Collection is still there
+		assertNotNull(submodelElement.getModelPropertyValue(VABPathTools.getParentPath(path)));
+
+		// Test, if it has been deleted
+		try {
+			submodelElement.getModelPropertyValue(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.getModelPropertyValue(VABPathTools.getParentPath(path)));
+
+		// Test, if it has been deleted
+		try {
+			submodelElement.getModelPropertyValue(path);
 			fail();
 		} catch (ResourceNotFoundException e) {}
 	}
@@ -234,21 +364,147 @@
 		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));
+		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/operations/complex", param1, param2);
+		Object result = submodelElement.invokeOperation("/submodel/submodelElements/complex/invoke", param1, param2);
 		assertEquals(3, result);
 
 		// Invoke operation on parent element
-		result = submodelElement.invokeOperation("/submodel/operations/simple");
+		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.getModelPropertyValue("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"));
+	}
+	
+	@Test
+	public void testInvokeAsync() throws Exception {
+		VABElementProxy submodelElement = getConnectionManager().connectToVABElement(submodelAddr);
+		AsyncOperationHelper helper = new AsyncOperationHelper();
+		
+		String path = VABPathTools.concatenatePaths("submodel", MultiSubmodelElementProvider.ELEMENTS, AsyncOperationHelper.ASYNC_OP_ID);
+		submodelElement.setModelPropertyValue(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");
+		String requestId = (String) submodelElement.invokeOperation(path, param1, param2);
+		
+		String listPath = VABPathTools.concatenatePaths("submodel", MultiSubmodelElementProvider.ELEMENTS, AsyncOperationHelper.ASYNC_OP_ID, OperationProvider.INVOCATION_LIST);
+		
+		// Try correct operationId, wrong requestId
+		try {
+			submodelElement.getModelPropertyValue(VABPathTools.append(listPath, "nonexistent"));
+			fail();
+		} catch (ResourceNotFoundException e) {
+		}
+		
+		// Try wrong operationId, correct requestId
+		try {
+			submodelElement.getModelPropertyValue("/submodel/submodelElements/simple/invocationList/" + requestId);
+			fail();
+		} catch (ResourceNotFoundException e) {
+		}
+		
+		String requestPath = VABPathTools.append(listPath, requestId);
+		
+		// Check that it has not finished yet
+		Object result = submodelElement.getModelPropertyValue(requestPath);
+		assertEquals(result, OperationResult.EXECUTION_NOT_YET_FINISHED.toString());
+		
+		helper.releaseWaitingOperation();
+		
+		result = submodelElement.getModelPropertyValue(requestPath);
+		assertEquals(7, result);
+		
+		// Check if the async-invocation is deleted after retrieving its result
+		try {
+			submodelElement.getModelPropertyValue(requestPath);
+			fail();
+		} catch (ResourceNotFoundException e) {
+		}
+	}
+	
+	@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.setModelPropertyValue(path, helper.getAsyncExceptionOperation());
+
+		path = VABPathTools.concatenatePaths("submodel", MultiSubmodelElementProvider.ELEMENTS,
+				AsyncOperationHelper.ASYNC_EXCEPTION_OP_ID, "invoke?async=true");
+		
+		String requestId = (String) submodelElement.invokeOperation(path);
+		
+		String requestPath = VABPathTools.concatenatePaths("submodel", MultiSubmodelElementProvider.ELEMENTS,
+				AsyncOperationHelper.ASYNC_EXCEPTION_OP_ID, OperationProvider.INVOCATION_LIST, requestId);
+		
+		// Check that it has not finished yet
+		Object result = submodelElement.getModelPropertyValue(requestPath);
+		assertEquals(result, OperationResult.EXECUTION_NOT_YET_FINISHED.toString());
+		
+		helper.releaseWaitingOperation();
+		
+		
+		result = submodelElement.getModelPropertyValue(requestPath);
+		assertEquals(result, OperationResult.EXECUTION_ERROR.toString());
+		
+		// Check if the async-invocation is deleted after retrieving its result
+		try {
+			submodelElement.getModelPropertyValue(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, PropertyValueTypeDefHelper.getTypeWrapperFromObject(value));
+		return param;
+	}
 }
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..dfcc438 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,13 @@
 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 +20,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) {
@@ -34,18 +32,14 @@
 	 */
 	@Override
 	public String getModelPropertyValue(String path) {
-		try {
-			PrintWriterStub outputstream = new PrintWriterStub("test.txt", "ignore");
+		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;		
 	}
 
 	/**
@@ -54,16 +48,14 @@
 	 */
 	@Override
 	public String setModelPropertyValue(String path, String newValue) throws ProviderException {
-		try {
-			PrintWriterStub outputstream = new PrintWriterStub("test.txt", "ignore");
+		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 +64,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 +80,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 +97,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 +113,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/TestJson.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/coder/json/TestJson.java
index f42432d..70cb8ad 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
@@ -7,6 +7,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;
@@ -61,6 +62,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
 	 */
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..583d0a3 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
@@ -22,6 +22,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/model/VABModelMapTest.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/model/VABModelMapTest.java
index 7361dd6..4004ed9 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,7 @@
 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 +48,19 @@
 	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);
 	}
 
 }
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..c2d245a 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
@@ -58,7 +58,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/MapInvoke.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/MapInvoke.java
index df62326..0dc1511 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
@@ -3,6 +3,7 @@
 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 +23,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 +54,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/VABPathToolsTest.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/VABPathToolsTest.java
index 79efe0d..d895c92 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
@@ -169,15 +169,25 @@
 
 	@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));
+	}
+	
+	@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(""));
 	}
 }
\ No newline at end of file
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..d2639d9
--- /dev/null
+++ b/sdks/java/basys.sdk/src/test/resources/aas/factory/json/aasJsonSchemaV2.0.1_Example.json
@@ -0,0 +1,561 @@
+{
+  "assetAdministrationShells": [
+    {
+      "asset": {
+        "keys": [
+          {
+            "type": "Asset",
+            "local": true,
+            "value": "http://customer.com/assets/KHBVZJSQKIY",
+            "idType": "IRI"
+          }
+        ]
+      },
+      "submodels": [
+        {
+          "keys": [
+            {
+              "type": "Submodel",
+              "local": true,
+              "value": "http.//i40.customer.com/type/1/1/7A7104BDAB57E184",
+              "idType": "IRI"
+            }
+          ]
+        },
+        {
+          "keys": [
+            {
+              "type": "Submodel",
+              "local": true,
+              "value": "http://i40.customer.com/instance/1/1/AC69B1CB44F07935",
+              "idType": "IRI"
+            }
+          ]
+        },
+        {
+          "keys": [
+            {
+              "type": "Submodel",
+              "local": true,
+              "value": "http://i40.customer.com/type/1/1/1A7B62B529F19152",
+              "idType": "IRI"
+            }
+          ]
+        }
+      ],
+      "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": {
+            "dataObjectType": {
+              "name": "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": {
+                "dataObjectType": {
+                  "name": "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": {
+            "dataObjectType": {
+              "name": "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..4bd09b2 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
@@ -253,7 +253,7 @@
 						</aas:valueId>
 						<aas:value>qualifierValue</aas:value>
 						<aas:type>qualifierType</aas:type>
-						<aas:valueType>valueType</aas:valueType>
+						<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>
@@ -307,7 +307,7 @@
 									</aas:valueId>
 									<aas:value>qualifierValue</aas:value>
 									<aas:type>qualifierType</aas:type>
-									<aas:valueType>valueType</aas:valueType>
+									<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>
@@ -341,6 +341,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 +388,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 +413,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>
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..45897f7
--- /dev/null
+++ b/sdks/java/basys.vabClient/src/test/java/org/eclipse/basyx/vab/CppExceptions.java
@@ -0,0 +1,61 @@
+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..680a3a2
--- /dev/null
+++ b/sdks/java/basys.vabClient/src/test/java/org/eclipse/basyx/vab/CppMapInvoke.java
@@ -0,0 +1,72 @@
+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..14d4af4
--- /dev/null
+++ b/sdks/java/basys.vabClient/src/test/java/org/eclipse/basyx/vab/CppMapRead.java
@@ -0,0 +1,86 @@
+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..0a3b03e
--- /dev/null
+++ b/sdks/java/basys.vabClient/src/test/java/org/eclipse/basyx/vab/CppMapUpdate.java
@@ -0,0 +1,77 @@
+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..1b3754c
--- /dev/null
+++ b/sdks/java/basys.vabClient/src/test/java/org/eclipse/basyx/vab/CppTestCollectionProperty.java
@@ -0,0 +1,115 @@
+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..a3d8b8b
--- /dev/null
+++ b/sdks/java/basys.vabClient/src/test/java/org/eclipse/basyx/vab/CppTestProvider.java
@@ -0,0 +1,53 @@
+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/components/basyx.tck/basyx.tck.AASAggregator/src/test/java/org/eclipse/basyx/testsuite/regression/aas/aggregator/AASAggregatorTestApplication.java b/sdks/java/basys.vabClient/src/test/java/org/eclipse/basyx/vab/CppVABTestApplication.java
similarity index 69%
rename from components/basyx.tck/basyx.tck.AASAggregator/src/test/java/org/eclipse/basyx/testsuite/regression/aas/aggregator/AASAggregatorTestApplication.java
rename to sdks/java/basys.vabClient/src/test/java/org/eclipse/basyx/vab/CppVABTestApplication.java
index 99b430f..976296b 100644
--- a/components/basyx.tck/basyx.tck.AASAggregator/src/test/java/org/eclipse/basyx/testsuite/regression/aas/aggregator/AASAggregatorTestApplication.java
+++ b/sdks/java/basys.vabClient/src/test/java/org/eclipse/basyx/vab/CppVABTestApplication.java
@@ -1,17 +1,18 @@
-package org.eclipse.basyx.testsuite.regression.aas.aggregator;
+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 concrete test suite of the registry provider
+ * The main class that executes the test provider.
+ * Structure is based on the TCK
  * 
- * @author zhangzai
+ * @author espen
  *
  */
-public class AASAggregatorTestApplication {
-
+public class CppVABTestApplication {
 
 	public static void main(String[] args) {
 		// First argument is the inserted url
@@ -20,7 +21,7 @@
 		JUnitCore junit = new JUnitCore();
 		junit.addListener(new TextListener(System.out));
 
-		AASAggregatorSuiteWithDefinedURL.url = url;
+		VABClientTest.url = url;
 		Result result = junit.run(AASAggregatorSuite.class);
 
 		System.out.println("Finished. Result: Failures: " +
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..3a4f65a
--- /dev/null
+++ b/sdks/java/basys.vabClient/src/test/java/org/eclipse/basyx/vab/VABClientTest.java
@@ -0,0 +1,31 @@
+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..8d36c9e
--- /dev/null
+++ b/sdks/java/basys.vabServer/src/main/java/org/eclipse/basyx/vab/ServerApplication.java
@@ -0,0 +1,32 @@
+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..7627622
--- /dev/null
+++ b/sdks/java/basys.vabServer/src/main/java/org/eclipse/basyx/vab/SimpleVABElement.java
@@ -0,0 +1,65 @@
+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..2554222
--- /dev/null
+++ b/sdks/java/basys.vabServer/src/main/java/org/eclipse/basyx/vab/SimpleVABProvider.java
@@ -0,0 +1,41 @@
+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);
+		}
+	}
+}