diff --git a/.gitignore b/.gitignore
index 1ade888129707fa0cd8bd18bc1c0ba23ac113ce2..4507e2b5d1d158b4b46d9160ce12368fb222a23a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,7 +1,7 @@
 ## Ignore .openapi-generator Folder
 ##
 .openapi-generator/
-server/src/Org.OpenAPITools/.gitignore
+server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/.gitignore
 
 # Visual Studio cache/options directory
 .vs/
@@ -9,6 +9,9 @@ server/src/Org.OpenAPITools/.gitignore
 # Visual Studio solution
 *.sln
 
+# generated project-files
+*.csproj
+
 # build-jobs
 build.*
 
@@ -22,7 +25,7 @@ server/programs/MongoDB/
 !server/programs/MongoDB/readme.md
 
 #generated readme
-server/README.md
+server/worldstorage/README.md
 
 # all generated directories
 Attributes/
@@ -36,11 +39,8 @@ OpenAPI/
 Properties/
 wwwroot/
 
-# generated project-files
-*.csproj
-
 # generated Program.cs
-Program.cs
+#Program.cs
 
 # backup-files
 *.bak
diff --git a/.gitmodules b/.gitmodules
index 120fcda39cfee4122d0a409175f301b4a5405dda..54f9b6352793921f7bc974319072781cdb6780da 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,4 +1,7 @@
 [submodule "arf005"]
 	path = arf005
 	url = git@forge.etsi.org:arf/arf005.git
-	branch = develop
\ No newline at end of file
+	branch = develop
+[submodule "openapi"]
+	path = openapi
+	url = https://forge.etsi.org/rep/arf/openapi.git
diff --git a/server/.openapi-generator-ignore b/.openapi-generator-ignore
similarity index 84%
rename from server/.openapi-generator-ignore
rename to .openapi-generator-ignore
index cbd23cf64baafbfa18079cf451ee244ab18af239..38a29adafc14ce78675a6e1e9d59359e5eaf3b8d 100644
--- a/server/.openapi-generator-ignore
+++ b/.openapi-generator-ignore
@@ -22,16 +22,20 @@
 # Then explicitly reverse the ignore rule for a single file:
 #!docs/README.md
 
+#
+# ETSI - ISG - ARF
+#
+**\ETSI.ARF.OpenAPI.WorldStorage.csproj
 
+# Modules to initialize World Storage database, server....
+**/Program.cs
 **/Startup.cs
-**/appsettings.json
 **/Dockerfile
-**/docker-compose.yml
-**/.openapi-generator-ignore
-
+**/appsettings.json
 
-# ARF
 # Implementation of REST request and database functionalities
-#
-**/ControllersImpl
-**/Services
+**/ETSI-ARF
+
+# Design of some web pages
+**/wwwroot/portal
+**/wwwroot/index.html
\ No newline at end of file
diff --git a/arf005 b/arf005
deleted file mode 160000
index 533b9d3198b772c7b628b0ab0e0a144b89966b46..0000000000000000000000000000000000000000
--- a/arf005
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 533b9d3198b772c7b628b0ab0e0a144b89966b46
diff --git a/build-iis-docker-ws.bat b/build-iis-docker-ws.bat
new file mode 100644
index 0000000000000000000000000000000000000000..ef7ec22c27c2b9398e152f0e1807333decda86db
--- /dev/null
+++ b/build-iis-docker-ws.bat
@@ -0,0 +1,2 @@
+cd server\worldstorage\src\ETSI.ARF.OpenAPI.WorldStorage
+docker build -t etsi.arf.openapi.worldstorage .
\ No newline at end of file
diff --git a/docker-compose.bat b/docker-compose.bat
new file mode 100644
index 0000000000000000000000000000000000000000..81eda89a647ab99a76ade58d3594e5abba9f2b22
--- /dev/null
+++ b/docker-compose.bat
@@ -0,0 +1 @@
+docker-compose up -d --force-recreate --remove-orphans
\ No newline at end of file
diff --git a/docker-compose.yml b/docker-compose.yml
new file mode 100644
index 0000000000000000000000000000000000000000..0f23eca4742c5af318b6f37041442e46cb8c9a9a
--- /dev/null
+++ b/docker-compose.yml
@@ -0,0 +1,45 @@
+# Please refer https://aka.ms/HTTPSinContainer on how to setup an https developer certificate for your ASP .NET Core service.
+
+name: etsi_arf_server
+version: '1.0'
+
+networks:
+  minionetwork:
+    driver: bridge
+  vpcbr:
+    ipam:
+     config:
+       - subnet: 172.24.30.0/24        
+
+services:
+  mongod:
+    container_name: etsi_mongodb
+    image: mongo:latest
+    environment:
+      - PUID=1000
+      - PGID=1000
+    volumes:
+  #    - mongodbdata:/data/mongodb:rw
+      - C:/Fraunhofer/Servers/ETSI/MongoDB/data:/data/db:rw
+      - C:/Fraunhofer/Servers/ETSI/MongoDB/data-dump:/data/db-dump:rw
+  #    - D:/Fraunhofer/Servers/ETSI/MongoDB/mongod.yaml:/etc/mongod.conf:rw
+    ports:
+      - 27037:27017
+      - 27038:27018
+    networks:
+      vpcbr:
+        ipv4_address: 172.24.30.101   
+    restart: unless-stopped
+
+  etsiapi:
+    container_name: etsi_arf_iis_server
+    image: etsi.arf.openapi.worldstorage:latest
+    volumes:
+      - C:/Fraunhofer/Servers/ETSI/appsettings.json:/app/appsettings.json:rw
+      - C:/Fraunhofer/Servers/ETSI/WWWRoot:/app/wwwroot:rw
+    ports:
+      - 8082:44301
+    networks:
+      vpcbr:
+        ipv4_address: 172.24.30.100   
+    restart: unless-stopped
diff --git a/openapi b/openapi
new file mode 160000
index 0000000000000000000000000000000000000000..08aa3ca82b2f3d78ee765df3e0d9046b3ab81ba1
--- /dev/null
+++ b/openapi
@@ -0,0 +1 @@
+Subproject commit 08aa3ca82b2f3d78ee765df3e0d9046b3ab81ba1
diff --git a/readme.md b/readme.md
index 239c654ec05abb4110cc7e9b95e1dffc5d413f3f..7715c1703f55da421ea836d5522282614ac07657 100644
--- a/readme.md
+++ b/readme.md
@@ -11,7 +11,7 @@
 
 ---
 
-# Description
+# Description - Version for STF 669
 
 This repo should be used to construct a complete ASP-Net REST server compliant to the ARF World Storage API. It uses auto-generated ASP.NET server code. We propose to use the open source OpenAPI-Generator for this.
 
@@ -34,7 +34,7 @@ What you need:
 
 1.	Installed npm: https://phoenixnap.com/kb/install-node-js-npm-on-windows
 2.	Installed openapi generator with npm: https://openapi-generator.tech/docs/installation/
-3.	Installed docker (if you want to use it): https://www.docker.com/get-started 
+3.	Installed docker (recommanded): https://www.docker.com/get-started 
 
 # Code Generation
 
@@ -43,10 +43,10 @@ We provided the file `.openapi-generator-ignore` in `server`, which prevents ope
 ## Auto-generate server code
 Open a command shell and execute:
 ```
-  openapi-generator-cli generate -i arf005\API\openapi.yaml -g aspnetcore -o server
+  npx openapi-generator-cli generate -i openapi/API/worldstorage/worldstorageopenapi.yaml --additional-properties aspnetCoreVersion=5.0,packageName=ETSI.ARF.OpenAPI.WorldStorage,operationModifier=abstract,classModifier=abstract -g aspnetcore -o server/worldstorage
 ```
 
-Open the solution `Org.OpenAPITools.sln` (folder `server`) in Visual Studio:
+Open the solution `ETSI.ARF.OpenAPI.WorldStorage.sln` (folder `server/worldstorage`) in Visual Studio:
 
 ## In Visual Studio
 Open `NuGet Package Manager` and add `MongoDB.Driver`.
@@ -54,37 +54,41 @@ Open `NuGet Package Manager` and add `MongoDB.Driver`.
 ### File adaptations
 Change version number in all files if a new version is provided.
 
-### In the folder `Controllers`
-Change "`public class`" to "`public abstract class`".
+### Implementation folder (new)
+All custom files are now in the folder 'ETSI-ARF'. Nothing to do adapt manually after generation. But you have to provide the implementation of new endpoints because they are now directly declared as abstract (default).
 
-Compare files folder in "`ControllersImpl`" with the corresponding files in "`Controllers`" and adapt if necessary.
+The folder contains following subfolders:
+`Controllers`
 
-Methods should be the same with "`override`" instead of "`virtual`".
+Compare files folder in "`ETSI-ARF/Controllers`" with the corresponding files in "`Controllers`" and insert if necessary the new methods.
+
+Methods should be the same with "`override`" instead of "`abstract`".
 
 --- 
 
 #### If some files are missing (and only then!)
-Copy them from folder `Controllers`, rename them (append `Impl`) and handle them like the already existing files, i.e.:
-Change classnames by appending `Impl` to the original classnames (and change filenames accordingly) and inherit from original class in `Controllers` (instead of `ControllerBase`)
-
-..and replace `virtual` by `override` with all methods. 
-
 Add 
 ```
-  using Org.OpenAPITools.Services;
   using MongoDB.Driver;
 ```
 
-Add a private readonly service class variable like in the already existing files.
+Add a private readonly service class variable like in the already existing files, e.g.:
+```
+private readonly TrackableService _trackableService;
+```
 
 Add a constructor with this service class variable like in the already existing files.
+```
+public TrackablesApiControllerImpl(TrackableService trackableService)
+{
+    _trackableService = trackableService;
+}
+```
 
-Remove sample code and replace it by using the appropriate methods of the corresponding classes in the folder `Services` (which you may be have to create).
-
---- 
+Implement endpoint code using the appropriate MogoDB methods of the corresponding classes from the folder `Services` (which you may be have to create).
 
 ### In the folder `Models`
-Add to the classes to be stored in the database (i.e. `Trackable.cs`, `WorldAnchor.cs`, `WorldLink.cs`) : 
+Add to the classes to be stored in the database (i.e. `Trackable.cs`, `WorldAnchor.cs`, `WorldLink.cs`) inherited from `IModels` (definition of the extra UUID): 
 ```
   using MongoDB.Bson;
   using MongoDB.Bson.Serialization.Attributes;
@@ -109,6 +113,17 @@ If you don't have a MongoDB, follow the instructions in `readme.md` in `server/p
 
 ...and put MongoDB in folder `server/programs/MongoDB` (download MongoDB as zip-file from https://www.mongodb.com/try/download/community and unzip the file into this directory, so that the bin-directory is in this folder).
 
+## How to dump database 
+Execute the following command in docker:
+``` 
+  mongodump --db **insert database_name** --out /data-dump/`date +"%Y-%m-%d"`
+```
+
+## How to import database
+Execute the following command in docker:
+```
+  mongorestore --db **insert database_name** **insert path_to_bson_file**
+```
 
 # Use in Visual Studio
 Make sure, that an instance of MongoDB is running.
@@ -116,38 +131,28 @@ Make sure, that an instance of MongoDB is running.
 Start application with IIS Express.
 
 
-# Use within a Docker
+# Use API within a Docker
+
+## Creating the IIS docker ##
 Remove the substring `src/Org.OpenAPITools/` in Dockerfile (if not already done)
 
-open a command shell and generate docker by executing in `server/src/Org.OpenAPITools`:
+open a command shell and generate docker by executing:
 ```
-  docker build -t org.openapitools .
+  build-iis-docker-ws.bat
 ```
 
-## How to start
+## How to start (with Docker-Compose)
 The easiest way is to use docker-compose:
 
-Open a command shell and use docker-compose (if necessary adapt docker-compose.yml) by executing in `server/src/Org.OpenAPITools`:
+Open a command shell and use docker-compose (if necessary adapt docker-compose.yml) by executing`:
 ```
-  docker-compose up --force-recreate --remove-orphan --detach
+  docker-compose.bat
 ```
 
 Open http://localhost:8080/openapi/index.html in a web-browser, if you want to check the functionalities using SwaggerUI
 
 ## How to stop
-Open a command shell by executing in `server/src/Org.OpenAPITools`:
+Open a command shell by executing in `server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage`:
 ```
   docker-compose down
 ```
-
-## How to dump database 
-Execute the following command in docker:
-``` 
-  mongodump --db **insert database_name** --out /data-dump/`date +"%Y-%m-%d"`
-```
-
-## How to import database
-Execute the following command in docker:
-```
-  mongorestore --db **insert database_name** **insert path_to_bson_file**
-```
diff --git a/server/worldanalysis/.openapi-generator-ignore b/server/worldanalysis/.openapi-generator-ignore
new file mode 100644
index 0000000000000000000000000000000000000000..7484ee590a3894506cf063799b885428f95a71be
--- /dev/null
+++ b/server/worldanalysis/.openapi-generator-ignore
@@ -0,0 +1,23 @@
+# OpenAPI Generator Ignore
+# Generated by openapi-generator https://github.com/openapitools/openapi-generator
+
+# Use this file to prevent files from being overwritten by the generator.
+# The patterns follow closely to .gitignore or .dockerignore.
+
+# As an example, the C# client generator defines ApiClient.cs.
+# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line:
+#ApiClient.cs
+
+# You can match any string of characters against a directory, file or extension with a single asterisk (*):
+#foo/*/qux
+# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux
+
+# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
+#foo/**/qux
+# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux
+
+# You can also negate patterns with an exclamation (!).
+# For example, you can ignore all files in a docs folder with the file extension .md:
+#docs/*.md
+# Then explicitly reverse the ignore rule for a single file:
+#!docs/README.md
diff --git a/server/worldanalysis/README.md b/server/worldanalysis/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..ac3ce3def60533a7bcacb5549e0767e71ac7ee5f
--- /dev/null
+++ b/server/worldanalysis/README.md
@@ -0,0 +1,50 @@
+# ETSI.ARF.OpenAPI.WorldAnalysis - ASP.NET Core 5.0 Server
+
+API ensuring interoperability between Scene Management and a World Analysis service
+
+## Upgrade NuGet Packages
+
+NuGet packages get frequently updated.
+
+To upgrade this solution to the latest version of all NuGet packages, use the dotnet-outdated tool.
+
+
+Install dotnet-outdated tool:
+
+```
+dotnet tool install --global dotnet-outdated-tool
+```
+
+Upgrade only to new minor versions of packages
+
+```
+dotnet outdated --upgrade --version-lock Major
+```
+
+Upgrade to all new versions of packages (more likely to include breaking API changes)
+
+```
+dotnet outdated --upgrade
+```
+
+
+## Run
+
+Linux/OS X:
+
+```
+sh build.sh
+```
+
+Windows:
+
+```
+build.bat
+```
+## Run in Docker
+
+```
+cd src/ETSI.ARF.OpenAPI.WorldAnalysis
+docker build -t etsi.arf.openapi.worldanalysis .
+docker run -p 5000:8080 etsi.arf.openapi.worldanalysis
+```
diff --git a/server/worldanalysis/src/ETSI.ARF.OpenAPI.WorldAnalysis/.gitignore b/server/worldanalysis/src/ETSI.ARF.OpenAPI.WorldAnalysis/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..1ee53850b84cd478da00264a919c8180a746056e
--- /dev/null
+++ b/server/worldanalysis/src/ETSI.ARF.OpenAPI.WorldAnalysis/.gitignore
@@ -0,0 +1,362 @@
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+##
+## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
+
+# User-specific files
+*.rsuser
+*.suo
+*.user
+*.userosscache
+*.sln.docstates
+
+# User-specific files (MonoDevelop/Xamarin Studio)
+*.userprefs
+
+# Mono auto generated files
+mono_crash.*
+
+# Build results
+[Dd]ebug/
+[Dd]ebugPublic/
+[Rr]elease/
+[Rr]eleases/
+x64/
+x86/
+[Ww][Ii][Nn]32/
+[Aa][Rr][Mm]/
+[Aa][Rr][Mm]64/
+bld/
+[Bb]in/
+[Oo]bj/
+[Ll]og/
+[Ll]ogs/
+
+# Visual Studio 2015/2017 cache/options directory
+.vs/
+# Uncomment if you have tasks that create the project's static files in wwwroot
+#wwwroot/
+
+# Visual Studio 2017 auto generated files
+Generated\ Files/
+
+# MSTest test Results
+[Tt]est[Rr]esult*/
+[Bb]uild[Ll]og.*
+
+# NUnit
+*.VisualState.xml
+TestResult.xml
+nunit-*.xml
+
+# Build Results of an ATL Project
+[Dd]ebugPS/
+[Rr]eleasePS/
+dlldata.c
+
+# Benchmark Results
+BenchmarkDotNet.Artifacts/
+
+# .NET Core
+project.lock.json
+project.fragment.lock.json
+artifacts/
+
+# ASP.NET Scaffolding
+ScaffoldingReadMe.txt
+
+# StyleCop
+StyleCopReport.xml
+
+# Files built by Visual Studio
+*_i.c
+*_p.c
+*_h.h
+*.ilk
+*.meta
+*.obj
+*.iobj
+*.pch
+*.pdb
+*.ipdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.tmp_proj
+*_wpftmp.csproj
+*.log
+*.vspscc
+*.vssscc
+.builds
+*.pidb
+*.svclog
+*.scc
+
+# Chutzpah Test files
+_Chutzpah*
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opendb
+*.opensdf
+*.sdf
+*.cachefile
+*.VC.db
+*.VC.VC.opendb
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+*.sap
+
+# Visual Studio Trace Files
+*.e2e
+
+# TFS 2012 Local Workspace
+$tf/
+
+# Guidance Automation Toolkit
+*.gpState
+
+# ReSharper is a .NET coding add-in
+_ReSharper*/
+*.[Rr]e[Ss]harper
+*.DotSettings.user
+
+# TeamCity is a build add-in
+_TeamCity*
+
+# DotCover is a Code Coverage Tool
+*.dotCover
+
+# AxoCover is a Code Coverage Tool
+.axoCover/*
+!.axoCover/settings.json
+
+# Coverlet is a free, cross platform Code Coverage Tool
+coverage*.json
+coverage*.xml
+coverage*.info
+
+# Visual Studio code coverage results
+*.coverage
+*.coveragexml
+
+# NCrunch
+_NCrunch_*
+.*crunch*.local.xml
+nCrunchTemp_*
+
+# MightyMoose
+*.mm.*
+AutoTest.Net/
+
+# Web workbench (sass)
+.sass-cache/
+
+# Installshield output folder
+[Ee]xpress/
+
+# DocProject is a documentation generator add-in
+DocProject/buildhelp/
+DocProject/Help/*.HxT
+DocProject/Help/*.HxC
+DocProject/Help/*.hhc
+DocProject/Help/*.hhk
+DocProject/Help/*.hhp
+DocProject/Help/Html2
+DocProject/Help/html
+
+# Click-Once directory
+publish/
+
+# Publish Web Output
+*.[Pp]ublish.xml
+*.azurePubxml
+# Note: Comment the next line if you want to checkin your web deploy settings,
+# but database connection strings (with potential passwords) will be unencrypted
+*.pubxml
+*.publishproj
+
+# Microsoft Azure Web App publish settings. Comment the next line if you want to
+# checkin your Azure Web App publish settings, but sensitive information contained
+# in these scripts will be unencrypted
+PublishScripts/
+
+# NuGet Packages
+*.nupkg
+# NuGet Symbol Packages
+*.snupkg
+# The packages folder can be ignored because of Package Restore
+**/[Pp]ackages/*
+# except build/, which is used as an MSBuild target.
+!**/[Pp]ackages/build/
+# Uncomment if necessary however generally it will be regenerated when needed
+#!**/[Pp]ackages/repositories.config
+# NuGet v3's project.json files produces more ignorable files
+*.nuget.props
+*.nuget.targets
+
+# Microsoft Azure Build Output
+csx/
+*.build.csdef
+
+# Microsoft Azure Emulator
+ecf/
+rcf/
+
+# Windows Store app package directories and files
+AppPackages/
+BundleArtifacts/
+Package.StoreAssociation.xml
+_pkginfo.txt
+*.appx
+*.appxbundle
+*.appxupload
+
+# Visual Studio cache files
+# files ending in .cache can be ignored
+*.[Cc]ache
+# but keep track of directories ending in .cache
+!?*.[Cc]ache/
+
+# Others
+ClientBin/
+~$*
+*~
+*.dbmdl
+*.dbproj.schemaview
+*.jfm
+*.pfx
+*.publishsettings
+orleans.codegen.cs
+
+# Including strong name files can present a security risk
+# (https://github.com/github/gitignore/pull/2483#issue-259490424)
+#*.snk
+
+# Since there are multiple workflows, uncomment next line to ignore bower_components
+# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
+#bower_components/
+
+# RIA/Silverlight projects
+Generated_Code/
+
+# Backup & report files from converting an old project file
+# to a newer Visual Studio version. Backup files are not needed,
+# because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+UpgradeLog*.htm
+ServiceFabricBackup/
+*.rptproj.bak
+
+# SQL Server files
+*.mdf
+*.ldf
+*.ndf
+
+# Business Intelligence projects
+*.rdl.data
+*.bim.layout
+*.bim_*.settings
+*.rptproj.rsuser
+*- [Bb]ackup.rdl
+*- [Bb]ackup ([0-9]).rdl
+*- [Bb]ackup ([0-9][0-9]).rdl
+
+# Microsoft Fakes
+FakesAssemblies/
+
+# GhostDoc plugin setting file
+*.GhostDoc.xml
+
+# Node.js Tools for Visual Studio
+.ntvs_analysis.dat
+node_modules/
+
+# Visual Studio 6 build log
+*.plg
+
+# Visual Studio 6 workspace options file
+*.opt
+
+# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
+*.vbw
+
+# Visual Studio LightSwitch build output
+**/*.HTMLClient/GeneratedArtifacts
+**/*.DesktopClient/GeneratedArtifacts
+**/*.DesktopClient/ModelManifest.xml
+**/*.Server/GeneratedArtifacts
+**/*.Server/ModelManifest.xml
+_Pvt_Extensions
+
+# Paket dependency manager
+.paket/paket.exe
+paket-files/
+
+# FAKE - F# Make
+.fake/
+
+# CodeRush personal settings
+.cr/personal
+
+# Python Tools for Visual Studio (PTVS)
+__pycache__/
+*.pyc
+
+# Cake - Uncomment if you are using it
+# tools/**
+# !tools/packages.config
+
+# Tabs Studio
+*.tss
+
+# Telerik's JustMock configuration file
+*.jmconfig
+
+# BizTalk build output
+*.btp.cs
+*.btm.cs
+*.odx.cs
+*.xsd.cs
+
+# OpenCover UI analysis results
+OpenCover/
+
+# Azure Stream Analytics local run output
+ASALocalRun/
+
+# MSBuild Binary and Structured Log
+*.binlog
+
+# NVidia Nsight GPU debugger configuration file
+*.nvuser
+
+# MFractors (Xamarin productivity tool) working folder
+.mfractor/
+
+# Local History for Visual Studio
+.localhistory/
+
+# BeatPulse healthcheck temp database
+healthchecksdb
+
+# Backup folder for Package Reference Convert tool in Visual Studio 2017
+MigrationBackup/
+
+# Ionide (cross platform F# VS Code tools) working folder
+.ionide/
+
+# Fody - auto-generated XML schema
+FodyWeavers.xsd
diff --git a/server/worldanalysis/src/ETSI.ARF.OpenAPI.WorldAnalysis/Dockerfile b/server/worldanalysis/src/ETSI.ARF.OpenAPI.WorldAnalysis/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..1203a89ba3579798b30bb4b67e45538b2c42d7b5
--- /dev/null
+++ b/server/worldanalysis/src/ETSI.ARF.OpenAPI.WorldAnalysis/Dockerfile
@@ -0,0 +1,32 @@
+#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.
+
+# Container we use for final publish
+FROM mcr.microsoft.com/dotnet/core/aspnet:5.0-buster-slim AS base
+WORKDIR /app
+EXPOSE 80
+EXPOSE 443
+
+# Build container
+FROM mcr.microsoft.com/dotnet/core/sdk:5.0-buster AS build
+
+# Copy the code into the container
+WORKDIR /src
+COPY ["src/ETSI.ARF.OpenAPI.WorldAnalysis/ETSI.ARF.OpenAPI.WorldAnalysis.csproj", "ETSI.ARF.OpenAPI.WorldAnalysis/"]
+
+# NuGet restore
+RUN dotnet restore "ETSI.ARF.OpenAPI.WorldAnalysis/ETSI.ARF.OpenAPI.WorldAnalysis.csproj"
+COPY ["src/ETSI.ARF.OpenAPI.WorldAnalysis/", "ETSI.ARF.OpenAPI.WorldAnalysis/"]
+
+# Build the API
+WORKDIR "ETSI.ARF.OpenAPI.WorldAnalysis"
+RUN dotnet build "ETSI.ARF.OpenAPI.WorldAnalysis.csproj" -c Release -o /app/build
+
+# Publish it
+FROM build AS publish
+RUN dotnet publish "ETSI.ARF.OpenAPI.WorldAnalysis.csproj" -c Release -o /app/publish
+
+# Make the final image for publishing
+FROM base AS final
+WORKDIR /app
+COPY --from=publish /app/publish .
+ENTRYPOINT ["dotnet", "ETSI.ARF.OpenAPI.WorldAnalysis.dll"]
diff --git a/server/worldanalysis/src/ETSI.ARF.OpenAPI.WorldAnalysis/Program.cs b/server/worldanalysis/src/ETSI.ARF.OpenAPI.WorldAnalysis/Program.cs
new file mode 100644
index 0000000000000000000000000000000000000000..95e22062027cf8674a23366f548a3e07c48c5d15
--- /dev/null
+++ b/server/worldanalysis/src/ETSI.ARF.OpenAPI.WorldAnalysis/Program.cs
@@ -0,0 +1,33 @@
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.Extensions.Hosting;
+
+namespace ETSI.ARF.OpenAPI.WorldAnalysis
+{
+    /// <summary>
+    /// Program
+    /// </summary>
+    public class Program
+    {
+        /// <summary>
+        /// Main
+        /// </summary>
+        /// <param name="args"></param>
+        public static void Main(string[] args)
+        {
+            CreateHostBuilder(args).Build().Run();
+        }
+
+        /// <summary>
+        /// Create the host builder.
+        /// </summary>
+        /// <param name="args"></param>
+        /// <returns>IHostBuilder</returns>
+        public static IHostBuilder CreateHostBuilder(string[] args) =>
+            Host.CreateDefaultBuilder(args)
+                .ConfigureWebHostDefaults(webBuilder =>
+                {
+                   webBuilder.UseStartup<Startup>()
+                             .UseUrls("http://0.0.0.0:8080/");
+                });
+    }
+}
diff --git a/server/worldanalysis/src/ETSI.ARF.OpenAPI.WorldAnalysis/Startup.cs b/server/worldanalysis/src/ETSI.ARF.OpenAPI.WorldAnalysis/Startup.cs
new file mode 100644
index 0000000000000000000000000000000000000000..eca56318884a59c800e6719a1f8e6f8e2405d8c2
--- /dev/null
+++ b/server/worldanalysis/src/ETSI.ARF.OpenAPI.WorldAnalysis/Startup.cs
@@ -0,0 +1,144 @@
+/*
+ * World Analysis API
+ *
+ * API ensuring interoperability between Scene Management and a World Analysis service
+ *
+ * The version of the OpenAPI document: 1.0.0
+ * 
+ * Generated by: https://openapi-generator.tech
+ */
+
+using System;
+using System.IO;
+using System.Reflection;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Hosting;
+using Microsoft.OpenApi.Models;
+using Newtonsoft.Json.Converters;
+using Newtonsoft.Json.Serialization;
+using ETSI.ARF.OpenAPI.WorldAnalysis.Authentication;
+using ETSI.ARF.OpenAPI.WorldAnalysis.Filters;
+using ETSI.ARF.OpenAPI.WorldAnalysis.OpenApi;
+using ETSI.ARF.OpenAPI.WorldAnalysis.Formatters;
+
+namespace ETSI.ARF.OpenAPI.WorldAnalysis
+{
+    /// <summary>
+    /// Startup
+    /// </summary>
+    public class Startup
+    {
+        /// <summary>
+        /// Constructor
+        /// </summary>
+        /// <param name="configuration"></param>
+        public Startup(IConfiguration configuration)
+        {
+            Configuration = configuration;
+        }
+
+        /// <summary>
+        /// The application configuration.
+        /// </summary>
+        public IConfiguration Configuration { get; }
+
+        /// <summary>
+        /// This method gets called by the runtime. Use this method to add services to the container.
+        /// </summary>
+        /// <param name="services"></param>
+        public void ConfigureServices(IServiceCollection services)
+        {
+
+            // Add framework services.
+            services
+                // Don't need the full MVC stack for an API, see https://andrewlock.net/comparing-startup-between-the-asp-net-core-3-templates/
+                .AddControllers(options => {
+                    options.InputFormatters.Insert(0, new InputFormatterStream());
+                })
+                .AddNewtonsoftJson(opts =>
+                {
+                    opts.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
+                    opts.SerializerSettings.Converters.Add(new StringEnumConverter
+                    {
+                        NamingStrategy = new CamelCaseNamingStrategy()
+                    });
+                });
+            services
+                .AddSwaggerGen(c =>
+                {
+                    c.EnableAnnotations(enableAnnotationsForInheritance: true, enableAnnotationsForPolymorphism: true);
+                    
+                    c.SwaggerDoc("1.0.0", new OpenApiInfo
+                    {
+                        Title = "World Analysis API",
+                        Description = "World Analysis API (ASP.NET Core 5.0)",
+                        TermsOfService = new Uri("https://github.com/openapitools/openapi-generator"),
+                        Contact = new OpenApiContact
+                        {
+                            Name = "OpenAPI-Generator Contributors",
+                            Url = new Uri("https://github.com/openapitools/openapi-generator"),
+                            Email = ""
+                        },
+                        License = new OpenApiLicense
+                        {
+                            Name = "NoLicense",
+                            Url = new Uri("https://opensource.org/licenses/BSD-3-Clause")
+                        },
+                        Version = "1.0.0",
+                    });
+                    c.CustomSchemaIds(type => type.FriendlyId(true));
+                    c.IncludeXmlComments($"{AppContext.BaseDirectory}{Path.DirectorySeparatorChar}{Assembly.GetEntryAssembly().GetName().Name}.xml");
+
+                    // Include DataAnnotation attributes on Controller Action parameters as OpenAPI validation rules (e.g required, pattern, ..)
+                    // Use [ValidateModelState] on Actions to actually validate it in C# as well!
+                    c.OperationFilter<GeneratePathParamsValidationFilter>();
+                });
+                services
+                    .AddSwaggerGenNewtonsoftSupport();
+        }
+
+        /// <summary>
+        /// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
+        /// </summary>
+        /// <param name="app"></param>
+        /// <param name="env"></param>
+        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
+        {
+            if (env.IsDevelopment())
+            {
+                app.UseDeveloperExceptionPage();
+            }
+            else
+            {
+                app.UseHsts();
+            }
+
+            app.UseHttpsRedirection();
+            app.UseDefaultFiles();
+            app.UseStaticFiles();
+            app.UseSwagger(c =>
+                {
+                    c.RouteTemplate = "openapi/{documentName}/openapi.json";
+                })
+                .UseSwaggerUI(c =>
+                {
+                    // set route prefix to openapi, e.g. http://localhost:8080/openapi/index.html
+                    c.RoutePrefix = "openapi";
+                    //TODO: Either use the SwaggerGen generated OpenAPI contract (generated from C# classes)
+                    c.SwaggerEndpoint("/openapi/1.0.0/openapi.json", "World Analysis API");
+
+                    //TODO: Or alternatively use the original OpenAPI contract that's included in the static files
+                    // c.SwaggerEndpoint("/openapi-original.json", "World Analysis API Original");
+                });
+            app.UseRouting();
+            app.UseEndpoints(endpoints =>
+                {
+                    endpoints.MapControllers();
+                });
+        }
+    }
+}
diff --git a/server/worldanalysis/src/ETSI.ARF.OpenAPI.WorldAnalysis/appsettings.Development.json b/server/worldanalysis/src/ETSI.ARF.OpenAPI.WorldAnalysis/appsettings.Development.json
new file mode 100644
index 0000000000000000000000000000000000000000..e203e9407e74a6b9662aab8fde5d73ae64665f18
--- /dev/null
+++ b/server/worldanalysis/src/ETSI.ARF.OpenAPI.WorldAnalysis/appsettings.Development.json
@@ -0,0 +1,9 @@
+{
+  "Logging": {
+    "LogLevel": {
+      "Default": "Debug",
+      "System": "Information",
+      "Microsoft": "Information"
+    }
+  }
+}
diff --git a/server/worldanalysis/src/ETSI.ARF.OpenAPI.WorldAnalysis/appsettings.json b/server/worldanalysis/src/ETSI.ARF.OpenAPI.WorldAnalysis/appsettings.json
new file mode 100644
index 0000000000000000000000000000000000000000..def9159a7d9403c04a926f64e71ef3ee7c9e4c57
--- /dev/null
+++ b/server/worldanalysis/src/ETSI.ARF.OpenAPI.WorldAnalysis/appsettings.json
@@ -0,0 +1,8 @@
+{
+  "Logging": {
+    "LogLevel": {
+      "Default": "Warning"
+    }
+  },
+  "AllowedHosts": "*"
+}
diff --git a/server/worldstorage/.openapi-generator-ignore b/server/worldstorage/.openapi-generator-ignore
new file mode 100644
index 0000000000000000000000000000000000000000..38a29adafc14ce78675a6e1e9d59359e5eaf3b8d
--- /dev/null
+++ b/server/worldstorage/.openapi-generator-ignore
@@ -0,0 +1,41 @@
+# OpenAPI Generator Ignore
+# Generated by openapi-generator https://github.com/openapitools/openapi-generator
+
+# Use this file to prevent files from being overwritten by the generator.
+# The patterns follow closely to .gitignore or .dockerignore.
+
+# As an example, the C# client generator defines ApiClient.cs.
+# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line:
+#ApiClient.cs
+
+# You can match any string of characters against a directory, file or extension with a single asterisk (*):
+#foo/*/qux
+# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux
+
+# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
+#foo/**/qux
+# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux
+
+# You can also negate patterns with an exclamation (!).
+# For example, you can ignore all files in a docs folder with the file extension .md:
+#docs/*.md
+# Then explicitly reverse the ignore rule for a single file:
+#!docs/README.md
+
+#
+# ETSI - ISG - ARF
+#
+**\ETSI.ARF.OpenAPI.WorldStorage.csproj
+
+# Modules to initialize World Storage database, server....
+**/Program.cs
+**/Startup.cs
+**/Dockerfile
+**/appsettings.json
+
+# Implementation of REST request and database functionalities
+**/ETSI-ARF
+
+# Design of some web pages
+**/wwwroot/portal
+**/wwwroot/index.html
\ No newline at end of file
diff --git a/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/Dockerfile b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..1d802b381d537ef7a107138148f635129f6a5e42
--- /dev/null
+++ b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/Dockerfile
@@ -0,0 +1,32 @@
+#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.
+
+# Container we use for final publish
+FROM mcr.microsoft.com/dotnet/aspnet:5.0-buster-slim AS base
+WORKDIR /app
+EXPOSE 80
+EXPOSE 443
+
+# Build container
+FROM mcr.microsoft.com/dotnet/sdk:5.0-buster-slim AS build
+
+# Copy the code into the container
+WORKDIR /src
+COPY ["ETSI.ARF.OpenAPI.WorldStorage.csproj", "ETSI.ARF.OpenAPI.WorldStorage/"]
+
+# NuGet restore
+RUN dotnet restore "ETSI.ARF.OpenAPI.WorldStorage/ETSI.ARF.OpenAPI.WorldStorage.csproj"
+COPY [".", "ETSI.ARF.OpenAPI.WorldStorage/"]
+
+# Build the API
+WORKDIR "ETSI.ARF.OpenAPI.WorldStorage"
+RUN dotnet build "ETSI.ARF.OpenAPI.WorldStorage.csproj" -c Release -o /app/build
+
+# Publish it
+FROM build AS publish
+RUN dotnet publish "ETSI.ARF.OpenAPI.WorldStorage.csproj" -c Release -o /app/publish
+
+# Make the final image for publishing
+FROM base AS final
+WORKDIR /app
+COPY --from=publish /app/publish .
+ENTRYPOINT ["dotnet", "ETSI.ARF.OpenAPI.WorldStorage.dll"]
diff --git a/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/Services/BaseService.cs b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/Services/BaseService.cs
new file mode 100644
index 0000000000000000000000000000000000000000..2e1e8cd20f075246799805acf4d48032155098a9
--- /dev/null
+++ b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/Services/BaseService.cs
@@ -0,0 +1,214 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using System.Net.NetworkInformation;
+
+using MongoDB.Driver;
+using MongoDB.Bson;
+using MongoDB.Bson.Serialization;
+using MongoDB.Bson.Serialization.Serializers;
+using ETSI.ARF.OpenAPI.WorldStorage.Models;
+using Microsoft.AspNetCore.Mvc;
+
+
+#pragma warning disable CS1591 // Fehlendes XML-Kommentar für öffentlich sichtbaren Typ oder Element
+namespace ETSI.ARF.OpenAPI.WorldStorage.Services
+{
+    abstract public class BaseService<T>
+    {
+        // The object is created by first access? so the singleton may be null if nothing here was called before
+        static public BaseService<T> Singleton => _singleton;
+        static protected BaseService<T> _singleton = null;
+
+        public IDatabaseSettings Settings => _settings;
+        protected IDatabaseSettings _settings;
+
+        protected string mongoServer;
+        protected MongoClient mongoClient;
+        protected IMongoDatabase mongoDatabase;
+        protected IMongoCollection<T> mongoCollection;
+
+        public BaseService(IDatabaseSettings settings)
+        {
+            // Store the singleton
+            if (_singleton != null) throw new Exception("Service can only be instantiated one time!");
+            else _singleton = this;
+
+            _settings = settings;
+
+            // Open the mongo database
+            //BsonSerializer.RegisterSerializer(new GuidSerializer(GuidRepresentation.Standard));
+            mongoServer = SelectMongoServer(settings);
+            mongoClient = new MongoClient(mongoServer);
+            mongoDatabase = mongoClient.GetDatabase(settings.DatabaseName);
+        }
+
+        ~BaseService()
+        {
+            // to do?
+        }
+
+        // Check manually if a GUID document already exists!
+        public bool CheckIfExist(Guid GUID)
+        {
+            foreach (var obj in Get())
+            {
+                if (((Models.IModels)obj).GUID == GUID) return true;
+            }
+            return false;
+        }
+
+        public long NumOfDocuments()
+        {
+            if (mongoCollection == null) return -1;
+            else return mongoCollection.CountDocuments(new BsonDocument());
+        }
+
+        private void _print(T obj)
+        {
+            Console.WriteLine("[Mongo Server] User # " + ((Models.IModels)obj).GUID);
+        }
+
+        public void PrintAll()
+        {
+            // Execute a _print to all elements
+            var a = mongoCollection.Find(_ => true);
+            a.ForEachAsync(_print).Wait();
+        }
+
+        public T Create(T obj)
+        {
+            // Test first if GUID doesn't exist
+            bool exist = CheckIfExist(((Models.IModels)obj).GUID);
+            if (!exist)
+            {
+                mongoCollection.InsertOne(obj);
+                return obj;
+            }
+            else return default(T);
+        }
+
+        //
+        // Get the current mongo _id of the object in the database
+        //
+        #region Get current mongo ID or object/document
+        private Guid _newObjGUID;
+        private T _currentObj;
+        private ObjectId _currentMongoID;
+        private ObjectId getMongoIDFromName(string name)
+        {
+            var res = mongoCollection.Find(obj => ((Models.IModels)obj).Name == name).FirstOrDefault();
+            if (res == null) return ObjectId.Empty;
+            else return ((Models.IModels)res)._mongoID;
+        }
+
+        private ObjectId getMongoIDFromGUID(Guid GUID)
+        {
+            _newObjGUID = GUID;
+            _currentMongoID = ObjectId.Empty;
+            var i = mongoCollection.Find(_ => true);
+            i.ForEachAsync(_compareAndRemember).Wait();
+            return _currentMongoID;
+        }
+
+        private void _compareAndRemember(T obj)
+        {
+            if (_currentMongoID != ObjectId.Empty) return; // take the first one
+            if (((Models.IModels)obj).GUID == _newObjGUID)
+            {
+                _currentObj = obj;
+                _currentMongoID = ((Models.IModels)obj)._mongoID;
+            }
+        }
+        #endregion
+
+        //abstract public long Replace(T obj);
+        public long Replace(T obj) //=> assetCollection.ReplaceOne(asset => asset.GUID == GUID, obj);
+        {
+            // Which mongo document?
+            ObjectId mongoID = getMongoIDFromGUID(((Models.IModels)obj).GUID);
+
+            // Object was found, so replace it using the _id
+            if (mongoID != ObjectId.Empty)
+            {
+                ((Models.IModels)obj)._mongoID = mongoID;
+                return mongoCollection.ReplaceOne(o => ((Models.IModels)o)._mongoID == mongoID, obj).MatchedCount;
+            }
+            else return 0;
+        }
+
+        public long Remove(T obj) => Remove(((Models.IModels)obj).GUID);
+
+        public long Remove(Guid GUID)
+        {
+            //return mongoCollection.DeleteOne(o => ((Models.IModels)o).GUID == GUID);
+
+            // Which mongo document?
+            ObjectId mongoID = getMongoIDFromGUID(GUID);
+
+            // Object was found, so replace it using the _id
+            if (mongoID != ObjectId.Empty)
+            {
+                // todo: check if the user is allowed to delete the object!
+
+                return mongoCollection.DeleteOne(o => ((Models.IModels)o)._mongoID == mongoID).DeletedCount;
+            }
+            else return 0;
+        }
+
+        // Return all documents
+        public List<T> Get() => mongoCollection.Find(_ => true).ToList();
+
+        // Limit the result to the first n documents
+        public List<T> Get(int limit) => mongoCollection.Find(_ => true).Limit(limit).ToList();
+
+        // Search manually the document with the id GUID
+        public T Get(string name) => mongoCollection.Find(obj => ((Models.IModels)obj).Name == name).FirstOrDefault();
+
+        // Geht nicht! public override T Get(Guid GUID) => mongoCollection.Find<T>(o => o.GUID == GUID).FirstOrDefault();
+        // Work around: look in all elements if the GUIDs are equals
+        public T Get(Guid GUID)
+        {
+            foreach (T obj in Get())
+            {
+                if (((Models.IModels)obj).GUID == GUID) return obj;
+            }
+            return default(T);
+        }
+
+        //
+        // Select the server or use a local database
+        //
+        private string SelectMongoServer(IDatabaseSettings settings)
+        {
+            string server = null;
+            Ping myPing = new Ping();
+            try
+            {
+                PingReply reply = myPing.Send(settings.MongoSrv, 1000);
+                if (reply != null)
+                {
+                    server = settings.MongoSrv;
+                    Console.WriteLine("[Mongo Server] Status: " + reply.Status + " \n Time: " + reply.RoundtripTime.ToString() + " \n Address: " + reply.Address);
+                }
+            }
+            catch (PingException e)
+            {
+                server = null;
+                Console.WriteLine("[Mongo Server] Ping: " + e.ToString());
+            }
+
+            if (server is null)
+            {
+                // Use the local mongo server
+                server = "localhost";
+                Console.WriteLine("[Mongo Server] Take localhost");
+            }
+            server = "mongodb://" + server + ":" + settings.MongoPort + "/";
+            mongoServer = server;
+            return server;
+        }
+    }
+}
+#pragma warning restore CS1591 // Fehlendes XML-Kommentar für öffentlich sichtbaren Typ oder Element
diff --git a/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/Services/DatabaseSettings.cs b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/Services/DatabaseSettings.cs
new file mode 100644
index 0000000000000000000000000000000000000000..197907ff85d146cf300dbed5a78f035f2f0d9f09
--- /dev/null
+++ b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/Services/DatabaseSettings.cs
@@ -0,0 +1,31 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+#pragma warning disable CS1591
+namespace ETSI.ARF.OpenAPI.WorldStorage.Services
+{
+    public interface IDatabaseSettings
+    {
+        string LocalDataPath { get; set; }
+        string DatabaseName { get; set; }
+        string MongoSrv { get; set; }
+        string MongoPort { get; set; }
+        public string CollectionNameWorldLink { get; set; }
+        public string CollectionNameTrackables { get; set; }
+        public string CollectionNameWorldAnchor { get; set; }
+    }
+
+    public class DatabaseSettings : IDatabaseSettings
+    {
+        public string LocalDataPath { get; set; }
+        public string DatabaseName { get; set; }
+        public string MongoSrv { get; set; }
+        public string MongoPort { get; set; }
+        public string CollectionNameWorldLink { get; set; }
+        public string CollectionNameTrackables { get; set; }
+        public string CollectionNameWorldAnchor { get; set; }
+    }
+}
+#pragma warning restore CS1591 // Fehlendes XML-Kommentar für öffentlich sichtbaren Typ oder Element
diff --git a/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/Program.cs b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/Program.cs
new file mode 100644
index 0000000000000000000000000000000000000000..a99fc849c853d1c2efb1e3a0af4c9a7fc995776f
--- /dev/null
+++ b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/Program.cs
@@ -0,0 +1,35 @@
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.Extensions.Hosting;
+using System;
+
+namespace ETSI.ARF.OpenAPI.WorldStorage
+{
+    /// <summary>
+    /// Program
+    /// </summary>
+    public class Program
+    {
+        /// <summary>
+        /// Main
+        /// </summary>
+        /// <param name="args"></param>
+        public static void Main(string[] args)
+        {
+            Console.WriteLine("ETSI ARF ASP.Net server started.");
+            CreateHostBuilder(args).Build().Run();
+        }
+
+        /// <summary>
+        /// Create the host builder.
+        /// </summary>
+        /// <param name="args"></param>
+        /// <returns>IHostBuilder</returns>
+        public static IHostBuilder CreateHostBuilder(string[] args) =>
+            Host.CreateDefaultBuilder(args)
+                .ConfigureWebHostDefaults(webBuilder =>
+                {
+                   webBuilder.UseStartup<Startup>()
+                             .UseUrls("http://0.0.0.0:44301/");     // SylR: Wichtig!!!
+                });
+    }
+}
diff --git a/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/Startup.cs b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/Startup.cs
new file mode 100644
index 0000000000000000000000000000000000000000..a6299c1ad9a818f15596520c4261a9cc81017778
--- /dev/null
+++ b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/Startup.cs
@@ -0,0 +1,194 @@
+/*
+ * World Storage API
+ *
+ * API ensuring interoperability between an authoring tool and a World Storage service
+ *
+ * The version of the OpenAPI document: 1.0.0
+ * 
+ * Generated by: https://openapi-generator.tech
+ */
+
+using System;
+using System.IO;
+using System.Reflection;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Hosting;
+using Microsoft.OpenApi.Models;
+using Newtonsoft.Json.Converters;
+using Newtonsoft.Json.Serialization;
+using ETSI.ARF.OpenAPI.WorldStorage.Authentication;
+using ETSI.ARF.OpenAPI.WorldStorage.Filters;
+using ETSI.ARF.OpenAPI.WorldStorage.OpenApi;
+using ETSI.ARF.OpenAPI.WorldStorage.Formatters;
+using ETSI.ARF.OpenAPI.WorldStorage.Services;
+using MongoDB.Bson.Serialization.Serializers;
+using MongoDB.Bson.Serialization;
+using MongoDB.Bson;
+using Microsoft.Extensions.Options;
+
+namespace ETSI.ARF.OpenAPI.WorldStorage
+{
+    /// <summary>
+    /// Startup
+    /// </summary>
+    public class Startup
+    {
+        //
+        // SylR, Fraunhofer HHI
+        //
+        /// <summary>
+        /// The API version. (how to read it from the yaml?)
+        /// </summary>
+        static public string apiVersion = "1.0.0";
+
+        /// <summary>
+        /// Demo access key
+        /// </summary>
+        static public string accessKey = "My!Key.ETSI";
+
+        /// <summary>
+        /// Demo secret key
+        /// </summary>
+        static public string secretKey = "GW0Wae1t4Cs5rAqEbPYFWO9J5nSbpJXxp1F3uv0J";
+
+        /// <summary>
+        /// Constructor
+        /// </summary>
+        /// <param name="configuration"></param>
+        public Startup(IConfiguration configuration)
+        {
+            Configuration = configuration;
+        }
+
+        /// <summary>
+        /// The application configuration.
+        /// </summary>
+        public IConfiguration Configuration { get; }
+
+        /// <summary>
+        /// SylR: Check if the request is authorized
+        /// </summary>
+        /// <param name="security"></param>
+        /// <returns></returns>
+        //static public bool IsAccessAllowed(ETSI.ARF.OpenAPI.WorldStorage.Models.SecureAccess security)
+        //{
+        //    Console.WriteLine(security.AccessKey);
+        //    return true;
+        //    //return (security.AccessKey == accessKey && security.SecretKey == secretKey);
+        //}
+
+        /// <summary>
+        /// This method gets called by the runtime. Use this method to add services to the container.
+        /// </summary>
+        /// <param name="services"></param>
+        public void ConfigureServices(IServiceCollection services)
+        {
+            //
+            // SylR, Fraunhofer HHI
+            //
+
+            // appsetting.json - requires using Microsoft.Extensions.Options
+            services.Configure<DatabaseSettings>(Configuration.GetSection(nameof(DatabaseSettings)));
+
+            //
+            // MongoDB
+            //
+            BsonSerializer.RegisterSerializer(new GuidSerializer(GuidRepresentation.Standard));
+            //BsonDefaults.GuidRepresentationMode = GuidRepresentationMode.V3;
+            var s = services.AddSingleton<IDatabaseSettings>(sp => sp.GetRequiredService<IOptions<DatabaseSettings>>().Value);
+            //services.AddSingleton<JobService>();
+            //services.AddSingleton<AssetService>();
+
+            // Add framework services.
+            services
+                // Don't need the full MVC stack for an API, see https://andrewlock.net/comparing-startup-between-the-asp-net-core-3-templates/
+                .AddControllers(options => {
+                    options.InputFormatters.Insert(0, new InputFormatterStream());
+                })
+                .AddNewtonsoftJson(opts =>
+                {
+                    opts.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
+                    opts.SerializerSettings.Converters.Add(new StringEnumConverter
+                    {
+                        NamingStrategy = new CamelCaseNamingStrategy()
+                    });
+                });
+            services
+                .AddSwaggerGen(c =>
+                {
+                    c.EnableAnnotations(enableAnnotationsForInheritance: true, enableAnnotationsForPolymorphism: true);
+                    
+                    c.SwaggerDoc(apiVersion, new OpenApiInfo
+                    {
+                        Title = "World Storage API",
+                        Description = "World Storage API (ASP.NET Core 5.0)",
+                        TermsOfService = new Uri("https://github.com/openapitools/openapi-generator"),
+                        Contact = new OpenApiContact
+                        {
+                            Name = "OpenAPI-Generator Contributors",
+                            Url = new Uri("https://github.com/openapitools/openapi-generator"),
+                            Email = ""
+                        },
+                        License = new OpenApiLicense
+                        {
+                            Name = "NoLicense",
+                            Url = new Uri("https://opensource.org/licenses/BSD-3-Clause")
+                        },
+                        Version = apiVersion,
+                    });
+                    c.CustomSchemaIds(type => type.FriendlyId(true));
+                    c.IncludeXmlComments($"{AppContext.BaseDirectory}{Path.DirectorySeparatorChar}{Assembly.GetEntryAssembly().GetName().Name}.xml");
+
+                    // Include DataAnnotation attributes on Controller Action parameters as OpenAPI validation rules (e.g required, pattern, ..)
+                    // Use [ValidateModelState] on Actions to actually validate it in C# as well!
+                    c.OperationFilter<GeneratePathParamsValidationFilter>();
+                });
+                services
+                    .AddSwaggerGenNewtonsoftSupport();
+        }
+
+        /// <summary>
+        /// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
+        /// </summary>
+        /// <param name="app"></param>
+        /// <param name="env"></param>
+        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
+        {
+            if (env.IsDevelopment())
+            {
+                app.UseDeveloperExceptionPage();
+            }
+            else
+            {
+                app.UseHsts();
+            }
+
+            app.UseHttpsRedirection();
+            app.UseDefaultFiles();
+            app.UseStaticFiles();
+            app.UseSwagger(c =>
+                {
+                    c.RouteTemplate = "openapi/{documentName}/openapi.json";
+                })
+                .UseSwaggerUI(c =>
+                {
+                    // set route prefix to openapi, e.g. http://localhost:8080/openapi/index.html
+                    c.RoutePrefix = "openapi";
+                    //TODO: Either use the SwaggerGen generated OpenAPI contract (generated from C# classes)
+                    //c.SwaggerEndpoint("/openapi/" + apiVersion  + "/openapi.json", "World Storage API");
+
+                    //TODO: Or alternatively use the original OpenAPI contract that's included in the static files
+                    c.SwaggerEndpoint("/openapi-original.json", "World Storage API Original");
+                });
+            app.UseRouting();
+            app.UseEndpoints(endpoints =>
+                {
+                    endpoints.MapControllers();
+                });
+        }
+    }
+}
diff --git a/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/_appsettings.json b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/_appsettings.json
new file mode 100644
index 0000000000000000000000000000000000000000..def9159a7d9403c04a926f64e71ef3ee7c9e4c57
--- /dev/null
+++ b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/_appsettings.json
@@ -0,0 +1,8 @@
+{
+  "Logging": {
+    "LogLevel": {
+      "Default": "Warning"
+    }
+  },
+  "AllowedHosts": "*"
+}
diff --git a/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/appsettings.Development.json b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/appsettings.Development.json
new file mode 100644
index 0000000000000000000000000000000000000000..e203e9407e74a6b9662aab8fde5d73ae64665f18
--- /dev/null
+++ b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/appsettings.Development.json
@@ -0,0 +1,9 @@
+{
+  "Logging": {
+    "LogLevel": {
+      "Default": "Debug",
+      "System": "Information",
+      "Microsoft": "Information"
+    }
+  }
+}
diff --git a/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/appsettings.json b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/appsettings.json
new file mode 100644
index 0000000000000000000000000000000000000000..7b6341fa51bd43caf5b07f8bfc1872c553c0dbb2
--- /dev/null
+++ b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/appsettings.json
@@ -0,0 +1,18 @@
+{
+  "DatabaseSettings": {
+    "Description" :  "Version for IIS",
+    "LocalDataPath": ".\\wwwroot\\dataspace\\data",
+    "MongoSrv": "localhost",
+    "MongoPort": "27017",
+    "DatabaseName": "WorldStorageAPI",
+    "CollectionNameWorldLink": "WorldLink",
+    "CollectionNameTrackables": "Trackables",
+    "CollectionNameWorldAnchor": "WorldAnchor"
+  },
+  "Logging": {
+    "LogLevel": {
+      "Default": "Warning"
+    }
+  },
+  "AllowedHosts": "*"
+}